如何将 Spring RestTemplate 中的自动编组自定义为 produce/modify XML headers(编码,DOCTYPE)
How to customize automatic marshaling in Spring RestTemplate to produce/modify XML headers (encoding, DOCTYPE)
我想了解如何影响 Spring 自动 封送 Java object 到 XML 的方式通过 RestTemplate
发送 POST 请求。特别是,如何配置 XML headers (encoding
, DOCTYPE
, ...).
中的内容
有很多问题与主题密切相关 (Include DOCTYPE for Spring Jaxb2Marshaller, How to add DOCTYPE and xml processing instructions when marshalling with JAXB?, , ),但其中 none 似乎对这里有所帮助。
我知道我可以先将 object 编组为 XML 字符串,然后再发送 XML 字符串。但是,我想使用自动编组,因为它看起来更优雅和适当。
我有一个class喜欢
@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>
元素。
您可以将 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,如果你有很多地方可以将它注入
我想了解如何影响 Spring 自动 封送 Java object 到 XML 的方式通过 RestTemplate
发送 POST 请求。特别是,如何配置 XML headers (encoding
, DOCTYPE
, ...).
有很多问题与主题密切相关 (Include DOCTYPE for Spring Jaxb2Marshaller, How to add DOCTYPE and xml processing instructions when marshalling with JAXB?,
我知道我可以先将 object 编组为 XML 字符串,然后再发送 XML 字符串。但是,我想使用自动编组,因为它看起来更优雅和适当。
我有一个class喜欢
@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>
元素。
您可以将 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,如果你有很多地方可以将它注入