Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generics with Spring RESTTemplate

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

like image 396
kamaci Avatar asked Nov 13 '11 01:11

kamaci


People also ask

Is RestTemplate outdated?

RestTemplate provides a synchronous way of consuming Rest services, which means it will block the thread until it receives a response. RestTemplate is deprecated since Spring 5 which means it's not really that future proof.

Is WebClient better than RestTemplate?

Compared to RestTemplate , WebClient has a more functional feel and is fully reactive. Since Spring 5.0, RestTemplate is deprecated. It will probably stay for some more time but will not have major new features added going forward in future releases. So it's not advised to use RestTemplate in new code.

Should I replace RestTemplate with WebClient?

If you need such a functionality, then yes you need to replace your Resttemplate with WebClient. You can in fact achieve Rest template like synchronous processing in webclient using . block() . But the other way is not possible.

What is the alternative for RestTemplate in spring boot?

reactive. client. WebClient offers a modern alternative to the RestTemplate with efficient support for both sync and async, as well as streaming scenarios. The RestTemplate will be deprecated in a future version and will not have major new features added going forward.


2 Answers

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.

like image 74
Manimaran Selvan Avatar answered Oct 14 '22 07:10

Manimaran Selvan


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.

like image 40
Juan Luis Avatar answered Oct 14 '22 07:10

Juan Luis