ClassCastException: RestTemplate returning List<LinkedHashMap> instead of List<MymodelClass>
I'm trying to access getter methods on my MyModelClass but my code is returning List<LinkedHashMap>
instead of List<MyModelClass>
. This is my code.
List<MyModelClass> myModelClass=(List<MyModelClass>) restTemplate.postForObject(url,mvm,List.class);
System.out.println("Response= " + myModelClass);
I tried to print the response and I got the JSON Response that I'm expecting. but when I tried to run this code.
System.out.println("Response= " + myModelClass.get(0).getMessage());
It will produce this error.
java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to com.XXX.XXX.MyModelClass
It is a mismatch. Can someone help me to get rid with this error? thanks.
MyModelClass
public class MyModelClass{
/**
*
*/
@JsonProperty("id")
public String id;
@JsonProperty("type")
public String type;
@JsonProperty("user")
public String user;
@JsonProperty("message")
public String message;
//getters
Error for
MyModelClass[] myModelClass= restTemplate.postForObject(url,mvm, myModelClass[].class);
org.springframework.http.converter.HttpMessageNotReadableException: Could not read JSON: Can not deserialize instance of java.util.ArrayList out of START_OBJECT token
JSON Response Structure
[{"key1":"value1","key2":"value2","parameters":{"key1":"value1","key2":"value2","key3":"value3","key4":"value4","key5":"value5"}},
{"key12":"value12","key22":"value22","parameters":{"key12":"value12","key22":"value22","key32":"value32","key42":"value42","key52":"value52"}}]
If there is any suggestion on how to map this kind of JSON Response in RestTemplate,It would help a lot. thanks
Solution 1:
With the following method call
List<MyModelClass> myModelClass=(List<MyModelClass>) restTemplate.postForObject(url,mvm,List.class);
All Jackson knows is that you want a List
, but doesn't have any restriction on the type. By default Jackson deserializes a JSON object into a LinkedHashMap
, so that's why you are getting the ClassCastException
.
If your returned JSON is an array, one way to get it is to use an array
MyModelClass[] myModelClasses = restTemplate.postForObject(url,mvm, MyModelClass[].class);
You can always add the elements from that array to a List
.
I can't remember since what version, but RestTemplate#exchange
now has an overload that accepts a ParameterizedTypeReference
argument. The ParameterizedTypeReference
is the type token hack for suggesting a parameterized type as the target for deserialization.
You can refactor the code above to use exchange
instead of postForObject
, and use ParameterizedTypeReference
to get a List<MyModelClass>
. For example
ParameterizedTypeReference<List<MyModelClass>> typeRef = new ParameterizedTypeReference<List<MyModelClass>>() {
};
ResponseEntity<List<MyModelClass>> responseEntity = restTemplate.exchange(url, HttpMethod.POST, new HttpEntity<>(mvm), typeRef);
List<MyModelClass> myModelClasses = responseEntity.getBody();