如何在Spring RestTemplate中自定义自动封送以生成/修改XML头(编码,DOCTYPE)

问题描述 投票:0回答:1

我想找到如何影响Spring在通过RestTemplate发送POST请求时如何自动将Java对象编组为XML。特别是,如何配置XML头文件中的内容(encodingDOCTYPE,...)。

有很多问题都在密切关注这个话题(Include DOCTYPE for Spring Jaxb2MarshallerHow to add DOCTYPE and xml processing instructions when marshalling with JAXB?how to add DOCTYPE in jaxb marshallerHow to declare doctype ,xml version and encoding in XML file using DOM parser in java?),但它们似乎都没有帮助。

enter image description here

我知道我可以先将对象编组为XML字符串然后发送XML字符串。但是,我想使用自动编组,因为它看起来更优雅和恰当。

我有一个类似的课程

@XmlRootElement(name = "MyRequest")
public class MyRequest {
    @XmlAttribute(required = true)
    String field1;
    @XmlAttribute(required = true)
    String field2;
    ...
}

发送HTTP POST请求的代码如下:

final MyRequest requestBody = new MyRequest("VALUE1", "VALUE2");

final HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_XML);
headers.setAccept(Arrays.asList(MediaType.APPLICATION_XML, MediaType.ALL));
final HttpEntity<MyRequest> requestHttpEntity = new HttpEntity<>(requestBody, headers);

return restTemplate.postForEntity(url, requestHttpEntity, MyResponse.class);

当我拦截发送的内容时,它是这样的:

POST /webservice HTTP/1.1
Accept: application/xml, */*
Content-Type: application/xml
Host: example.com:8080
Content-Length: ...

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<MyRequest field1="VALUE1" field2="VALUE2">
</MyRequest>

而我想要收到的是

POST ...

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE MyRequest SYSTEM "MyRequest.dtd">
<MyRequest field1="VALUE1" field2="VALUE2">
</MyRequest>

问题:如何在不完全避免Spring RestTemplate的自动行为的情况下自定义编组?我想更改encoding,删除standalone属性(它来自哪里?)并添加<!DOCTYPE>元素。

java xml spring marshalling resttemplate
1个回答
2
投票

您可以将RestTemplate使用的XML转换器替换为自定义的转换器:

RestTemplate restTemplate = new RestTemplate();
List<HttpMessageConverter<?>> converters = restTemplate.getMessageConverters();
for (int i = 0; i != converters.size(); i++) {
    if (converters.get(i) instanceof Jaxb2RootElementHttpMessageConverter) {
        Jaxb2RootElementHttpMessageConverter xmlConverter = new Jaxb2RootElementHttpMessageConverter(){
            @Override
            protected void customizeMarshaller(Marshaller marshaller) {
                marshaller.setProperty( "com.sun.xml.internal.bind.xmlHeaders", "<!DOCTYPE MyRequest SYSTEM \"MyRequest.dtd\">");
                // add other customizations
            }
        };
        converters.set(i, xmlConverter);
        break;
    }
}

将整个事物包装在一个用@Bean @Qualified注释的方法中,并使用它在任何需要的地方自动装配RestTemplate,如果你有很多地方可以注入它

© www.soinside.com 2019 - 2024. All rights reserved.