如何在Spring RestTemplate中自定义自动封送处理以生成/修改XML标头(编码,DOCTYPE) [英] How to customize automatic marshaling in Spring RestTemplate to produce/modify XML headers (encoding, DOCTYPE)

查看:735
本文介绍了如何在Spring RestTemplate中自定义自动封送处理以生成/修改XML标头(编码,DOCTYPE)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'd like to find how to influence how Spring automatically marshals Java objects to XML when sending a POST request via RestTemplate. Particularly, how to configure what is in the XML headers (encoding, DOCTYPE, ...).

有很多与主题密切相关的问题(包括Spring Jaxb2Marshaller的DOCTYPE 如何在jaxb marshaller中添加DOCTYPE 如何使用Java中的DOM解析器在XML文件中声明doctype,xml版本和编码吗?),但似乎没有一个帮助.

There are plenty of questions closely touching the topic (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?) but none of them seems to help here.

我知道我可以先将对象编组为XML字符串,然后再发送XML字符串.但是,我想使用自动封送处理,因为它看起来更优雅,更合适.

I am aware that I may marshal the object to XML string first and then send the XML string. However, I'd like to use the automatic marshaling as it seems more elegant and proper.

我有一个类似的课程

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

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

The code sending the HTTP POST request is like:

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);

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

When I intercept what is sent, it is something like this:

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>元素.

Question: How can I customize the marshaling without completely avoiding the automagic behavior of Spring RestTemplate? I want to change the encoding, remove the standalone attribute (where does it come from?) and add the <!DOCTYPE> element.

推荐答案

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

You can replace the XML converter that RestTemplate uses with a customized one:

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自动连接

Wrap the whole thing in a method annotated with @Bean @Qualified, and use that to autowire the RestTemplate wherever you need it, if you have many places to inject it to

这篇关于如何在Spring RestTemplate中自定义自动封送处理以生成/修改XML标头(编码,DOCTYPE)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆