Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/94.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Spring RestTemplate无法解组包含“的XML”&书信电报;!DOCTYPE。。。dtd>&引用;_Java_Xml_Spring_Unmarshalling_Resttemplate - Fatal编程技术网

Java Spring RestTemplate无法解组包含“的XML”&书信电报;!DOCTYPE。。。dtd>&引用;

Java 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()方

我调用由第三方提供的旧web服务。我正在使用Spring
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在使用时返回10
messageConverters
它打印1。可能是由于不同的依赖项、JDK等。默认情况下启用哪些转换器取决于类路径上的内容。