7

I have a problem when Consume Rest Service with RestTemplate in Desktop App whereas the problem doesn't appear when i use in Web app.

This Is the Debugging logs

15:30:40.448 [main] DEBUG o.s.web.client.RestTemplate - Reading [java.util.List] as "application/json" using [org.springframework.http.converter.json.MappingJacksonHttpMessageConverter@98adae2]
15:30:40.452 [main] DEBUG httpclient.wire.content - << "[{"name":"Indonesia","id":1},{"name":"AlaySia","id":2},{"name":"Autraliya","id":3}]"

Exception in thread "main" java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to com.mgm.domain.Country

And this is the Code that i use.

 String url = "http://localhost:8080/mgm/country";
    List<MediaType> mediaTypes = new ArrayList<MediaType>();
    mediaTypes.add(MediaType.APPLICATION_JSON);
    HttpHeaders headers = new HttpHeaders();
    headers.setAccept(mediaTypes);
    HttpEntity<Country> httpEntity = new HttpEntity<Country>(null, headers);
    try {
        ResponseEntity<List> responseEntity = restTemplate.exchange(url, HttpMethod.GET, httpEntity, List.class);
        List<Country> countries = responseEntity.getBody();
        System.out.println(countries.get(0).getName());

    } catch (RestClientException exception) {
        exception.printStackTrace();
    }

Code above doesn't give errors when i place it in web app. I use Spring Rest MVC to Provide JSON and Consume it with RestTemplate.

I think there is a problem when Jackson Convert java.util.LinkedHashMap to Country . it Seems that countries.get(0) actually has LinkedHashMap type not Country and problem will appeared when i invoke one of Country methode like .getName()

skaffman
  • 381,978
  • 94
  • 789
  • 754
  • to all: one point to noted, RestTemplate is located in spring-web jar. So its a part of spring web project. – Kowser Aug 17 '11 at 14:11

1 Answers1

22

Try using an array instead:

String url = "http://localhost:8080/mgm/country";
List<MediaType> mediaTypes = new ArrayList<MediaType>();
mediaTypes.add(MediaType.APPLICATION_JSON);
HttpHeaders headers = new HttpHeaders();
headers.setAccept(mediaTypes);
HttpEntity<Country> httpEntity = new HttpEntity<Country>(null, headers);
try {
    ResponseEntity<Country[]> responseEntity = restTemplate.exchange(url, HttpMethod.GET, httpEntity, Country[].class);
    Country[] countries = responseEntity.getBody();
    System.out.println(countries[0].getName());

} catch (RestClientException exception) {
    exception.printStackTrace();
}
stoffer
  • 2,127
  • 2
  • 16
  • 24
  • +1. Having the same issue, after some research on this I discovered your solution, came here to answer it, and see you beat me to it :-) The reason apparently is that you can't pass `List.class` to the `exchange()` method, so when it unmarshalls it has no way to know the type (`Country`) the `List` is typed to. Arrays can be passed as `Class` objects, so the type information can be conveyed to the underlying unmarshaller. – SingleShot Aug 17 '11 at 15:55
  • yes, this is due to type erasure effects in the generics mechanism of Java. More found here: http://stackoverflow.com/questions/339699/java-generics-type-erasure-when-and-what-happens just adding my 2 cents – Tobi Nonymous Dec 19 '14 at 09:08