"的 XML-6ren"> "的 XML-我调用了第三方提供的旧网络服务。我正在使用 Spring RestTemplate: HttpEntity requestHttpEntity = new HttpEntity<>(requestBo-6ren">
gpt4 book ai didi

java - Spring RestTemplate 无法解码包含 "<!DOCTYPE ... dtd>"的 XML

转载 作者:行者123 更新时间:2023-12-05 01:43:57 24 4
gpt4 key购买 nike

我调用了第三方提供的旧网络服务。我正在使用 Spring RestTemplate:

HttpEntity<MyRequest> requestHttpEntity = new HttpEntity<>(requestBody, headers);
MyResponse response = restTemplate.postForEntity(url, requestHttpEntity, MyResponse.class);

我收到一个 XML(我无法影响其格式,它是第三方服务)作为响应:

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE MyResponse SYSTEM "http://example.com:8080/some/path/MyResponse.dtd">

<MyResponse>
...
</MyResponse>

postForEntity() 方法抛出异常

org.springframework.web.client.RestClientException: 
Error while extracting response for type [class com.example.MyResponse] and content type [text/xml;charset=ISO-8859-1];
nested exception is org.springframework.http.converter.HttpMessageNotReadableException:
Could not unmarshal to [class com.example.MyResponse]: null;
nested exception is javax.xml.bind.UnmarshalException

- with linked exception:
[org.xml.sax.SAXParseException; lineNumber: 2; columnNumber: 10;
DOCTYPE is disallowed when the feature
"http://apache.org/xml/features/disallow-doctype-decl" set to true.]

我在此处找到了对 http://apache.org/xml/features/disallow-doctype-decl 功能的唯一合理引用:https://xerces.apache.org/xerces2-j/features.html#disallow-doctype-decl

问题:如何在不完全避免 Spring RestTemplate 的自动行为的情况下自定义解码?我想强制解码器接受包含带有 DTD 引用的元素的 XML。

这个问题与我的另一个问题密切相关How to customize automatic marshaling in Spring RestTemplate to produce/modify XML headers (encoding, DOCTYPE) , 但这里提出的解决方案并不容易适用。

最佳答案

默认 Jaxb2RootElementHttpMessageConverter禁用 DTD 支持(以及 XML 实体支持)。这样做的原因是它具有安全隐患,请参阅 SPR-11376 .

Jaxb2RootElementHttpMessageConverter 上启用它您可以将 supportDtd 属性设置为 true 以再次启用它。但请注意,这也会带来一些潜在的安全问题!。

@Bean
public Jaxb2RootElementHttpMessageConverter jaxb2RootElementHttpMessageConverter() {
Jaxb2RootElementHttpMessageConverter converter = new Jaxb2RootElementHttpMessageConverter();
converter.setSupportDtd(true);
return converter;
}

这应该足以(重新)配置支持,而无需添加任何额外的配置。要记住的一件事是,这将配置全局可用的 Jaxb2RootElementHttpMessageConverter,因此会影响您可能想要使用的所有 Controller 和 RestTemplate

除此之外,您还可以使用 RestTemplateBuilder,您在创建 RestTemplate 的实例时应该使用它来仅影响特定的 RestTemplate

@Bean
public RestTemplate yourRestTemplate(RestTemplateBuilder builder) {
Jaxb2RootElementHttpMessageConverter converter = new Jaxb2RootElementHttpMessageConverter();
converter.setSupportDtd(true);

return builder.messageConverters(converter).build()
}

通过这种方式,您可以针对 RestTemplate 实例对其进行特定配置,并根据您的喜好进行配置。

关于java - Spring RestTemplate 无法解码包含 "&lt;!DOCTYPE ... dtd>"的 XML,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47854054/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com