XML : Spring RestTemplate GetForObject giving an XML specific exception for a JSON response

I'm writing the integration for a couple API service calls; one of those services was simple. A quick Item item = restTemplate.getForObject(url, Item.class) where Item is just a POJO and everything was mapped right into that object.

The other service is problematic. The call is almost the same: Attribute[] attribute = restTemplate.getForObject(url, Attribute[].class) with the difference being that the JSON response has a top level array. Here's the Attribute class:

  @Data public class ItemAttributes {        private Long id;      private Attribute[] attributes;        @Data      private static class Attribute {          private String name;          //a bunch of other fields      }  }    

All my digging says the above should work. Instead I get this:

   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    

And additional digging has just lead me in circles. First, that's an XML specific Exception for what I've double-checked is actually a JSON response. Second, even if it was XML, RestTemplate should automatically register the correct HttpMessageConverter and mapper. (Right? That's what the documentation says.)

If I use ResponseEntity<String> response = restTemplate.getForEntity(url, String.class) and print response.getBody().toString() I get something that looks like this:

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

I know I could run with that, create an ObjectMapper and a parser and grab what I want, but that doesn't address the bigger question of why the other approach isn't working, and why it's throwing that exception.

Any help will be greatly appreciated.

No comments:

Post a Comment