Generics with Spring RESTTemplate

JavaSpringGenericsJacksonResttemplate

Java Problem Overview


I have a class like that:

public class Wrapper<T> {

 private String message;
 private T data;

 public String getMessage() {
    return message;
 }

 public void setMessage(String message) {
    this.message = message;
 }
 
 public T getData() {
    return data;
 }

 public void setData(T data) {
    this.data = data;
 }

}

and I use resttemplate as follows:

...
Wrapper<Model> response = restTemplate.getForObject(URL, Wrapper.class, myMap);
Model model = response.getData();
...

However it throws a:

ClassCastException

I read that: https://stackoverflow.com/questions/4392326/problem-when-trying-to-use-jackson-in-java but didn't help. There are some topics related to my problem etc.: https://jira.springsource.org/browse/SPR-7002 and https://jira.springsource.org/browse/SPR-7023

Any ideas?

PS: My error is that:

java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to a.b.c.d.Model

I think resttemplate can not understand my generic variable and maybe it accepts it as an Object instead of generic T. So it becomes a LinkedHashMap. You can read from it here It says that when explaining from what it marshalls to:

> JSON Type | Java Type > > object | LinkedHashMap

Java Solutions


Solution 1 - Java

ParameterizedTypeReference has been introduced in 3.2 M2 to workaround this issue.

Wrapper<Model> response = restClient.exchange(loginUrl, 
                          HttpMethod.GET, 
                          null, 
                          new ParameterizedTypeReference<Wrapper<Model>>() {}).getBody();

However, the postForObject/getForObject variant was not introduced.

Solution 2 - Java

The only thing I think you could do is creating a new class that extends Wrapper and uses model as a generic.

class WrapperWithModel extends Wrapper<Model>{};

WrapperWithModel response = restTemplate.getForObject(URL, WrapperWithModel.class);

It's not the best solution, but at least you won't have to unmarshall manually the response.

Solution 3 - Java

Do not use generics with RestTemplate. Wrap request and response object with wrapper object that will hide the generics.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionkamaciView Question on Stackoverflow
Solution 1 - JavaManimaran SelvanView Answer on Stackoverflow
Solution 2 - JavaJuan LuisView Answer on Stackoverflow
Solution 3 - JavaDimaView Answer on Stackoverflow