Java Spring RestTemplate无法解组包含“的XML”&书信电报;!DOCTYPE。。。dtd>&引用;
我调用由第三方提供的旧web服务。我正在使用SpringJava Spring RestTemplate无法解组包含“的XML”&书信电报;!DOCTYPE。。。dtd>&引用;,java,xml,spring,unmarshalling,resttemplate,Java,Xml,Spring,Unmarshalling,Resttemplate,我调用由第三方提供的旧web服务。我正在使用SpringRestTemplate: HttpEntity requestHttpEntity=新的HttpEntity(requestBody,headers); MyResponse-response=restTemplate.postForEntity(url、requestHttpEntity、MyResponse.class); 我收到一个XML(我不能影响它的格式,它是第三方服务)作为响应: ... postForEntity()方
RestTemplate
:
HttpEntity requestHttpEntity=新的HttpEntity(requestBody,headers);
MyResponse-response=restTemplate.postForEntity(url、requestHttpEntity、MyResponse.class);
我收到一个XML(我不能影响它的格式,它是第三方服务)作为响应:
...
postForEntity()
方法引发异常
org.springframework.web.client.RestClientException:
为类型[class com.example.MyResponse]和内容类型[text/xml;charset=ISO-8859-1]提取响应时出错;
嵌套异常为org.springframework.http.converter.httpMessageEndableException:
无法解组到[class com.example.MyResponse]:null;
嵌套异常是javax.xml.bind.UnmarshalException
-除此之外:
[org.xml.sax.SAXParseException;行号:2;列号:10;
当该功能启动时,不允许使用DOCTYPE
"http://apache.org/xml/features/disallow-doctype-decl“设置为true。]
我找到了对http://apache.org/xml/features/disallow-doctype-decl
此处的功能:
问题:如何在不完全避免Spring RestTemplate的自动控制行为的情况下自定义解编程序?我想强制解编程序接受包含DTD引用的XML元素
这个问题与我的另一个问题密切相关,但这里提出的解决方案并不容易适用。默认情况下,禁用DTD支持(以及XML实体支持)。这样做的原因是它具有安全含义,请参阅
要在上启用它,可以将supportDtd
属性设置为true
以再次启用它。但请注意,这也会带来一些潜在的安全问题
@Bean
public Jaxb2RootElementHttpMessageConverter jaxb2RootElementHttpMessageConverter() {
Jaxb2RootElementHttpMessageConverter converter = new Jaxb2RootElementHttpMessageConverter();
converter.setSupportDtd(true);
return converter;
}
这应该足以(重新)配置支持,而无需添加任何其他配置。需要记住的一点是,这将配置全局可用的Jaxb2RootElementHttpMessageConverter
,因此将影响您可能要使用的所有控制器和restemplate
s
除此之外,您还可以使用restemplatebuilder
,在创建restemplate
实例时应使用该工具,以仅影响特定的restemplate
@Bean
public RestTemplate yourRestTemplate(RestTemplateBuilder builder) {
Jaxb2RootElementHttpMessageConverter converter = new Jaxb2RootElementHttpMessageConverter();
converter.setSupportDtd(true);
return builder.messageConverters(converter).build()
}
通过这种方式,您可以针对
RestTemplate
的实例对其进行特定配置,并根据需要进行配置。只需将该属性设置为false。。。您可以将HttpMessageConverter
配置为执行此操作。默认情况下,此属性设置为false
禁用DTD支持,这与启用DTD支持时的安全影响有关。@M.Deinum它的工作原理很神奇(假设您的意思是将该属性设置为true:),谢谢!我以前没有注意到这种方法。请给我一个答案,我很乐意接受!你对我的相关问题也有这么简单的回答吗?Alex Savitsky的答案确实有效,但在我看来更像是一个黑客。请看这里的答案,特别是第二部分,它也应该回答您的另一个问题。两者都是错误的,您应该使用messageConverters
(至少对于Spring Boot 1.5.x)。这将替换所有现有的消息转换器,另一个将添加到默认转换器列表中。使用修改后的答案,您将获得一个带有单个消息转换器的restemplate
。那么您肯定缺少Spring Boot的一些其他部分。默认情况下,还会添加其他部分。如果您想保存,请使用messageConverters
而不是附加*
一个。。。在额外的情况下,我得到7个转换器,共(使用默认的JaxbRootElementHttpMessageConverter
而不是重新配置的转换器。使用messageconverter
我总共得到一个转换器,而不是重新配置的JaxbRootElementHttpMessageConverter
。它将为您提供一个新的转换器,builder.messageConverters(converter)的结果)
是一个新配置的RestTemplateBuilder
方法链接。如果不使用,您将无法获得新添加的转换器。此外,您应该使用它创建一个rest模板,而不是在每次需要模板时都使用它。不,在使用builder时不会使用它。additionalMessageConverters
mine在使用时返回10messageConverters
它打印1。可能是由于不同的依赖项、JDK等。默认情况下启用哪些转换器取决于类路径上的内容。