【问题标题】:Spring RestTemplate GetForObject giving an XML specific exception for a JSON responseSpring RestTemplate GetForObject 为 JSON 响应提供 XML 特定异常
【发布时间】:2016-03-24 20:35:31
【问题描述】:

我正在为几个 API 服务调用编写集成;其中一项服务很简单。快速的Item item = restTemplate.getForObject(url, Item.class),其中Item 只是一个 POJO,所有内容都直接映射到该对象中。

其他服务有问题。调用几乎相同:Attribute[] attribute = restTemplate.getForObject(url, Attribute[].class),不同之处在于 JSON 响应具有顶级数组。这是Attribute 类:

@Data public class ItemAttributes {

    private Long id;
    private Attribute[] attributes;

    @Data
    private static class Attribute {
        private String name;
        //a bunch of other fields
    }
}

我的所有挖掘都表明上述内容应该有效。相反,我得到了这个:

 org.springframework.http.converter.HttpMessageNotReadableException: Could not read 
document: javax.xml.stream.XMLStreamException: 
ParseError at [row,col]:[1,1]
Message: Content is not allowed in prolog.; nested exception is java.io.IOException: javax.xml.stream.XMLStreamException: 
ParseError at [row,col]:[1,1]
Message: Content is not allowed in prolog.

at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:224)
at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.read(AbstractJackson2HttpMessageConverter.java:208)
at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:95)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:599)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:557)
at org.springframework.web.client.RestTemplate.getForObject(RestTemplate.java:264)
at com.homedepot.order.gateway.resource.ItemAttributeServiceResource.getItemAttributes(ItemAttributeServiceResource.java:37)
at com.homedepot.order.gateway.resource.ItemAttributeServiceResource.getItemAttributes(ItemAttributeServiceResource.java:32)
at com.homedepot.order.gateway.resource.ItemAttributeServiceResourceTest.testStuffOneItem(ItemAttributeServiceResourceTest.java:62)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:85)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:639)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:821)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1131)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:124)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:108)
at org.testng.TestRunner.privateRun(TestRunner.java:773)
at org.testng.TestRunner.run(TestRunner.java:623)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:357)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:352)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:310)
at org.testng.SuiteRunner.run(SuiteRunner.java:259)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1185)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1110)
at org.testng.TestNG.run(TestNG.java:1018)
at org.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:72)
at org.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:122)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
Caused by: java.io.IOException: javax.xml.stream.XMLStreamException: ParseError at [row,col]:[1,1]
Message: Content is not allowed in prolog.
at com.fasterxml.jackson.dataformat.xml.util.StaxUtil.throwXmlAsIOException(StaxUtil.java:24)
at com.fasterxml.jackson.dataformat.xml.XmlFactory._createParser(XmlFactory.java:539)
at com.fasterxml.jackson.dataformat.xml.XmlFactory._createParser(XmlFactory.java:29)
at com.fasterxml.jackson.core.JsonFactory.createParser(JsonFactory.java:802)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2810)
at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:221)
... 36 more
Caused by: javax.xml.stream.XMLStreamException: ParseError at [row,col]:[1,1]
Message: Content is not allowed in prolog.
at com.sun.org.apache.xerces.internal.impl.XMLStreamReaderImpl.next(XMLStreamReaderImpl.java:596)
at com.fasterxml.jackson.dataformat.xml.XmlFactory._initializeXmlReader(XmlFactory.java:648)
at com.fasterxml.jackson.dataformat.xml.XmlFactory._createParser(XmlFactory.java:537)
... 40 more

额外的挖掘让我陷入了困境。首先,这是一个特定于 XML 的异常,因为我已经仔细检查过实际上是一个 JSON 响应。其次,即使它 XML,RestTemplate 也应该自动注册正确的 HttpMessageConverter 和映射器。 (对吧?文档是这么说的。)

如果我使用ResponseEntity<String> response = restTemplate.getForEntity(url, String.class) 并打印response.getBody().toString(),我会得到如下所示的内容:

[{"id":12345678,"attributes":[{"f1":"value1","f2":"value2","f3":"value3"},
{"f1":"value4","f2":"value5","f3":"value6"}]}]

我知道我可以使用它运行,创建一个 ObjectMapper 和一个解析器并获取我想要的东西,但这并不能解决 为什么 其他方法不起作用的更大问题,以及为什么抛出该异常。

任何帮助将不胜感激。

【问题讨论】:

    标签: java json xml spring


    【解决方案1】:

    两个潜在问题: 1)您确定 RestTemplate.getForObject 的通用版本可以接受数组类吗?传递“Attribute[].class”似乎不正确...... 2) 返回的 JSON 不是数组,而是地图。即使将数组类传递给 RestTemplate 有效,返回的数据也不匹配,解析将失败。

    ~NCM

    【讨论】:

      【解决方案2】:

      我的错。尽管 API 团队保证响应肯定是“application/json”,但我应该首先完成我的尽职调查并检查响应标题上的 Content-Type,因为它设置为“text/plain”。一旦他们修复,问题就解决了。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-08-04
        • 2018-01-16
        • 2020-07-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-02-24
        • 1970-01-01
        相关资源
        最近更新 更多