3

I have a SpringBoot app. with this config file:

@Configuration
public class ApplicationConfig {

    @Bean
    public RestTemplate restTemplate() {
        RestTemplate restTemplate = new RestTemplate();
        MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
        mappingJackson2HttpMessageConverter.setSupportedMediaTypes(Arrays.asList(MediaType.APPLICATION_JSON, MediaType.APPLICATION_OCTET_STREAM));
        restTemplate.getMessageConverters().add(mappingJackson2HttpMessageConverter);
        return restTemplate;
    }

}

and this class:

@Builder
@Data
@NoArgsConstructor
@AllArgsConstructor
@JsonInclude(NON_NULL)
public class GeolocationAddress {

    private Integer placeId;
    private String licence;
    private String osmType;
    private Integer osmId;
    private List<String> boundingbox = null;
    private String lat;
    private String lon;
    private String displayName;
    private String _class;
    private String type;
    private Double importance;
    private Address address;
}

and this:

@Builder
@Data
@NoArgsConstructor
@AllArgsConstructor
@JsonInclude(NON_NULL)
public class GeolocationAddressList {

    private List<GeolocationAddress> addresses;

}

and this service:

public List<GeolocationAddress> searchFromAddress(String address) {

    HttpHeaders headers = new HttpHeaders();
    headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
    HttpEntity<String> entity = new HttpEntity<String>(headers);

    String url = "https://nominatim.openstreetmap.org/?addressdetails=1&q=bakery+in+berlin+wedding&format=json&limit=1";


    GeolocationAddressList geolocationAddressList
            = restTemplate.exchange(url, HttpMethod.GET, entity, GeolocationAddressList.class).getBody();

    return geolocationAddressList.getAddresses();
}

but I have this error when running the service:

org.springframework.web.client.RestClientException: Error while extracting response for type [class com.bonansa.domain.GeolocationAddressList] and content type [application/json;charset=UTF-8]; nested exception is org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize instance of `com.bonansa.domain.GeolocationAddressList` out of START_ARRAY token; nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `com.bonansa.domain.GeolocationAddressList` out of START_ARRAY token
 at [Source: (PushbackInputStream); line: 1, column: 1]

the JSON

[{"place_id":80416066,"licence":"Data © OpenStreetMap contributors, ODbL 1.0. https://osm.org/copyright","osm_type":"way","osm_id":4308033,"boundingbox":["40.4249225","40.4254227","-3.7133155","-3.7124476"],"lat":"40.42515745","lon":"-3.7128816738834214","display_name":"Plaza de Emilio Jiménez Millas, Argüelles, Moncloa-Aravaca, Madrid, Área metropolitana de Madrid y Corredor del Henares, Comunidad de Madrid, 28001, Comunidad de Madrid","class":"highway","type":"pedestrian","importance":0.42816097156854616,"address":{"road":"Plaza de Emilio Jiménez Millas","quarter":"Argüelles","city_district":"Moncloa-Aravaca","city":"Madrid","municipality":"Área metropolitana de Madrid y Corredor del Henares","state":"Comunidad de Madrid","postcode":"28001","country_code":"es","administrative":"Comunidad de Madrid"}}]
Jude Niroshan
  • 4,280
  • 8
  • 40
  • 62
Nuñito Calzada
  • 4,394
  • 47
  • 174
  • 301
  • some of the properties contains ```_``` in the JSON so better use ```@JsonProperty("display_name")``` on the attribute level like this. – prostý člověk Dec 06 '20 at 09:44
  • can you post correct json response here? did you hit request in postman/soapui and compare the resonse with your POJO class? – priyranjan Dec 06 '20 at 09:45
  • 1
    The response is an **array**, while you only parse to `GeolocationAddress.class`. `limit=1` does not give you a single entry, but an array with one element. Also, some properties contain `_` while your fields in `GeolocationAddress` don´t. – Glains Dec 06 '20 at 10:35

3 Answers3

3

The problem you are facing has to do with the way you are requesting the information.

You are performing a GET request to the service and trying to map the response as an instance of the GeolocationAddressList class.

Your code would work if the service actually returned an object with a property addresses corresponding to an array of GeolocationAddress.

But the service is actually returning the array of GeolocationAddress itself, and Jackson is complaining about it - as you indicated that you are waiting for an object but the service is actually returning an array.

Please, change your code to something like the following:

GeolocationAddress[] addresses
        = restTemplate.exchange(url, HttpMethod.GET, entity, GeolocationAddress[].class).getBody();

I think it should work.

jccampanero
  • 50,989
  • 3
  • 20
  • 49
3

Use ParameterizedTypeReference to map the response directly to List<GeolocationAddress> without needing the container object.

public List<GeolocationAddress> searchFromAddress(String address) {

  HttpHeaders headers = new HttpHeaders();
  headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
  HttpEntity<String> entity = new HttpEntity<String>(headers);

  String url = "https://nominatim.openstreetmap.org/?addressdetails=1&q=bakery+in+berlin+wedding&format=json&limit=1";

  ParameterizedTypeReference<List<GeolocationAddress>> typeRef = new ParameterizedTypeReference<List<GeolocationAddress>(){};
  List<GeolocationAddress> addresses = restTemplate.exchange(url, HttpMethod.GET, entity, typeRef).getBody();

  return addresses;
}
s7vr
  • 73,656
  • 11
  • 106
  • 127
0

change your call to

GeolocationAddress[] geolocationAddresses
        = restTemplate.exchange(url, HttpMethod.GET, entity, GeolocationAddress[].class).getBody();

this should work..

you can directly pass your array to:

java.util.Arrays#asList

which gives you then a List<GeolocationAddress>

Another benefit is that you can remove GeolocationAddressList since it is not needed anymore.

Bernd Farka
  • 502
  • 2
  • 9