Reputation: 75257
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: Issue 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
Upvotes: 94
Views: 87524
Reputation: 336
If you want to do it in a generic methode you can use ResolvableType from spring.
public <T> Wrapper<T> getObject(String loginUrl, Class<T> clazz) {
ResolvableType resolvableType = ResolvableType.forClassWithGenerics(Wrapper.class, clazz);
return restClient.exchange(loginUrl,
HttpMethod.GET,
null,
ParameterizedTypeReference.forType(resolvableType.getType()))
.getBody();
}
Upvotes: 3
Reputation: 3357
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.
Upvotes: 14
Reputation: 2266
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.
Upvotes: 180
Reputation: 1794
Do not use generics with RestTemplate. Wrap request and response object with wrapper object that will hide the generics.
Upvotes: 3