Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Could not read JSON: Can not deserialize instance of hello.Country[] out of START_OBJECT token

I have rest url that gives me all countries - http://api.geonames.org/countryInfoJSON?username=volodiaL.

I use RestTemplate from spring 3 to parse returned json into java objects:

RestTemplate restTemplate = new RestTemplate(); Country[] countries = restTemplate.getForObject("http://api.geonames.org/countryInfoJSON?username=volodiaL",Country[].class); 

When I run this code I get an exception:

Caused by: com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of hello.Country[] out of START_OBJECT token  at [Source: sun.net.www.protocol.http.HttpURLConnection$HttpInputStream@1846149; line: 1, column: 1]     at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:164)     at com.fasterxml.jackson.databind.DeserializationContext.mappingException(DeserializationContext.java:691)     at com.fasterxml.jackson.databind.DeserializationContext.mappingException(DeserializationContext.java:685)     at com.fasterxml.jackson.databind.deser.std.ObjectArrayDeserializer.handleNonArray(ObjectArrayDeserializer.java:222)     at com.fasterxml.jackson.databind.deser.std.ObjectArrayDeserializer.deserialize(ObjectArrayDeserializer.java:133)     at com.fasterxml.jackson.databind.deser.std.ObjectArrayDeserializer.deserialize(ObjectArrayDeserializer.java:18)     at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:2993)     at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2158)     at org.springframework.http.converter.json.MappingJackson2HttpMessageConverter.readJavaType(MappingJackson2HttpMessageConverter.java:225)     ... 7 more 

Finally my Country class:

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;  @JsonIgnoreProperties(ignoreUnknown = true) public class Country {     private String countryName;     private long geonameId;      public String getCountryName() {         return countryName;     }      public long getGeonameId() {         return geonameId;     }      @Override     public String toString() {         return countryName;     } } 

The problem is that returned json contains root element "geonames" which contains array of country elements like so:

{ "geonames": [     {         "continent": "EU",         "capital": "Andorra la Vella",         "languages": "ca",         "geonameId": 3041565,         "south": 42.42849259876837,         "isoAlpha3": "AND",         "north": 42.65604389629997,         "fipsCode": "AN",         "population": "84000",         "east": 1.7865427778319827,         "isoNumeric": "020",         "areaInSqKm": "468.0",         "countryCode": "AD",         "west": 1.4071867141112762,         "countryName": "Andorra",         "continentName": "Europe",         "currencyCode": "EUR"     } ] } 

How to tell RestTemplate to convert each element of array into Country object?

like image 399
Volodymyr Levytskyi Avatar asked Jul 21 '14 11:07

Volodymyr Levytskyi


1 Answers

You need to do the following:

public class CountryInfoResponse {     @JsonProperty("geonames")    private List<Country> countries;      //getter - setter }  RestTemplate restTemplate = new RestTemplate(); List<Country> countries = restTemplate.getForObject("http://api.geonames.org/countryInfoJSON?username=volodiaL",CountryInfoResponse.class).getCountries(); 

It would be great if you could use some kind of annotation to allow you to skip levels, but it's not yet possible (see this and this)

like image 82
geoand Avatar answered Sep 19 '22 14:09

geoand