我想了解如何影响Spring 在通过RestTemplate
发送POST请求时如何自动将Java对象编组为XML。特别是,如何配置XML标头中的内容(encoding
,DOCTYPE
,...)。
有很多问题与主题密切相关(Include DOCTYPE for Spring Jaxb2Marshaller,How to add DOCTYPE and xml processing instructions when marshalling with JAXB?,how to add DOCTYPE in jaxb marshaller,How to declare doctype ,xml version and encoding in XML file using DOM parser in java?),但这些问题似乎都没有帮助。
我知道我可以先将对象编组为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>
元素。
答案 0 :(得分: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,如果你有很多地方可以注入它