有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

我想了解在通过RestTemplate发送POST请求时,如何影响Spring自动将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>元素


共 (1) 个答案

  1. # 1 楼答案

    您可以将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,则可以使用该方法自动连接RestTemplate