23

I am making use of this cool thing Spring offers: Spring RESTWebService (Version of spring is 3). If I access the URL from browser I can see the JSON response, but from a Client endpoint (Android application) iIreceive this error message:

Caused by: org.springframework.web.client.ResourceAccessException: 
    I/O error: Can not deserialize instance of MyObject out of START_ARRAY token
  at [Source: org.apache.http.conn.EofSensorInputStream@4076e940; line: 1, 
    column: 1]; nested exception is org.codehaus.jackson.map.JsonMappingException: 
    Can not deserialize instance of MyObject  out of START_ARRAY token
  at [Source: org.apache.http.conn.EofSensorInputStream@4076e940; line: 1, column: 1]
   at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:466)
   at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:414)
   at org.springframework.web.client.RestTemplate.getForEntity(RestTemplate.java:234)
   at com.be.android.locateconsultants.resources.AsyncTaskRESTServiceCaller.doInBackground(AsyncTaskRESTServiceCaller.java:43)
   at com.be.android.locateconsultants.resources.AsyncTaskRESTServiceCaller.doInBackground(AsyncTaskRESTServiceCaller.java:1)
   at android.os.AsyncTask$2.call(AsyncTask.java:252)
   at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
   ... 4 more

 Caused by: org.codehaus.jackson.map.JsonMappingException: Can not deserialize 
    instance of MyObject  out of START_ARRAY token
  at [Source: org.apache.http.conn.EofSensorInputStream@4076e940; line: 1, column: 1]
   at org.codehaus.jackson.map.deser.StdDeserializationContext.mappingException(StdDeserializationContext.java:198)
   at org.codehaus.jackson.map.deser.BeanDeserializer.deserializeUsingCreator(BeanDeserializer.java:565)
   at org.codehaus.jackson.map.deser.BeanDeserializer.deserialize(BeanDeserializer.java:365)
   at org.codehaus.jackson.map.ObjectMapper._readMapAndClose(ObjectMapper.java:2395)
   at org.codehaus.jackson.map.ObjectMapper.readValue(ObjectMapper.java:1655)
   at org.springframework.http.converter.json.MappingJacksonHttpMessageConverter.readInternal(MappingJacksonHttpMessageConverter.java:135)
   at org.springframework.http.converter.AbstractHttpMessageConverter.read(AbstractHttpMessageConverter.java:154)
   at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:74)
   at org.springframework.web.client.RestTemplate$ResponseEntityResponseExtractor.extractData(RestTemplate.java:632)
   at org.springframework.web.client.RestTemplate$ResponseEntityResponseExtractor.extractData(RestTemplate.java:618)
   at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:459)
   ... 10 more

MyObject structure is the same as the one from the server side application.

I have tried to request the server like this:

final String url = ".....";
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<Consultant> responseEntity = restTemplate.getForEntity(
            url, Consultant.class);

Or like this:

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> entity = new HttpEntity<String>(headers);
ResponseEntity<MyObject> response = restTemplate
            .exchange("....",HttpMethod.GET, entity, MyObject.class);
System.out.println("RESPONSE: " + response.getBody());

But still the same error as above. Can't figure out what I am missing at this point, any idea or hints would be great. Thank you.

JJD
  • 47,369
  • 53
  • 194
  • 328
Gabriela Radu
  • 737
  • 2
  • 12
  • 32
  • What is the json structure, how MyObject looks. Not enough information. The only guess I see is that you're getting array from server and trying to map it to MyObject. – pawelzieba May 23 '12 at 12:34
  • in the client: `public class Consultant { private int id; private String firstName; private String lastName; private String phoneNumber; private String jobName; private String workAddress; private Date created; private String email; getters and setters } ` – Gabriela Radu May 23 '12 at 12:43
  • and the response json is this: `[{"id":1,"firstName":"first name","lastName":"last name","jobName":"programmer","created":1328133600000,"email":"test@yahoo.com","workAddress":"test","phoneNumber":"0000"},{...},{..}]` – Gabriela Radu May 23 '12 at 12:46
  • 1
    Yes, then you should map it to List rather than to Consultant.class. – pawelzieba May 23 '12 at 13:09
  • You are correct. Thank you. If you don't write the last comment as an answer I cannot tag your response as the correct one :D – Gabriela Radu May 23 '12 at 14:20

4 Answers4

23

You should map it to List<Consultant> rather than to Consultant.class.

pawelzieba
  • 16,024
  • 3
  • 43
  • 72
18

Solution in a similar situation was to map to Consultant[].class This applies if you try to deserialize a JSON array of your mapped objects.

Ahto Luuri
  • 238
  • 3
  • 12
9

This is related to Jackson and the way you're attempting to deserialize and initialize a container from an array.

While my usage context is a bit different, this may help some who get here from searching for Jackson-specific deserialization errors.

I had to do it like this:

List<Consultant> consultants = Arrays.asList(
    mapper.readValue(myJson.toString(), Consultants[].class)
);
JJD
  • 47,369
  • 53
  • 194
  • 328
NathanChristie
  • 2,354
  • 21
  • 20
0

a file foo.json contains a batch of data like this:

[{"A":"TYMH","B":"datab","C":"DLJQ","D":"datad"}, {"A":"TYMH","B":"datab","C":"DLJQ","D":"datad"}]

The following statement gives you an ArrayList of LinkedHashMap, where A B C D are the keys.

List list = mapper.readValue(new File("D:\\...\\foo.json"), List.class);
Tiina
  • 3,585
  • 4
  • 38
  • 64