Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to get a generic ResponseEntity<T> where T is a generic class "SomeClass<SomeGenericType>"

Please help me to get a ResponseEntity<T> where T is itself a generic type. As I see it of now, this is not supported nowdays by spring RestTemplate. I'm using Spring MVC version 3.1.2

Here is my code, that I want to use: Code:

ResponseEntity<CisResponse<CisResponseEntity>> res =          this.restTemplate.postForEntity(              this.rootURL, myRequestObj, CisResponse.class); 

I'm getting this error:

Type mismatch: cannot convert from ResponseEntity<CisResponse> to ResponseEntity<CisResponse<CisResponseEntity>> 

It's obvious error, but how I can workaround it today?

Than I do want to get my generic response type:

CisResponse<CisResponseEntity> myResponse= res.getBody(); CisResponseEntity entity = myResponse.getEntityFromResponse(); 

For now, I use this solution, with postForObject() and not postForEntity():

CisResponse<CisResponseEntity> response =            this.restTemplate.postForObject(                this.rootURL,myRequestObj, CisResponse.class); 
like image 958
IgorA Avatar asked Dec 11 '12 11:12

IgorA


People also ask

What is ResponseEntity class in Spring boot?

ResponseEntity represents the whole HTTP response: status code, headers, and body. As a result, we can use it to fully configure the HTTP response. If we want to use it, we have to return it from the endpoint; Spring takes care of the rest. ResponseEntity is a generic type.

What is the return type of ResponseEntity?

A ResponseEntity is returned. We give ResponseEntity a custom status code, headers, and a body. With @ResponseBody , only the body is returned. The headers and status code are provided by Spring.

What is ParameterizedTypeReference in Java?

ParameterizedTypeReference<List<String>> typeRef = new ParameterizedTypeReference<List<String>>() {}; The resulting typeRef instance can then be used to obtain a Type instance that carries the captured parameterized type information at runtime.

How do you use Resttemplate getForObject?

The getForObject method fetches the data for the given response type from the given URI or URL template using HTTP GET method. To fetch data for the given key properties from URL template we can pass Object Varargs and Map to getForObject method. The getForObject returns directly the object of given response type.


1 Answers

This was a known issue. Now it's fixed with the introduction of ParameterizedTypeReference, which is a parameterized type that you explicitely inherit to supply type information at runtime. This is called a super-type token, and works around type erasure because subclasses (anoniymous in this case) keep the type arguments of the generic supertype at runtime.

However you can't use postForObject, because the API only supports exchange():

ResponseEntity<CisResponse<CisResponseEntity>> res = template.exchange(         rootUrl,         HttpMethod.POST,         null,         new ParameterizedTypeReference<CisResponse<CisResponseEntity>>() {}); 

Note that the last line demonstrates the idea of super type tokens: you don't supply the literal CisResponse.class, but an anonymous instantiation of the parameterized type ParameterizedTypeReference<T>, which at runtime can be expected to extract subtype information. You can think of super type tokens as hacks for achieving Foo<Bar<Baz>>.class

BTW, in Java you don't need to prefix access to instance variable with this: if your object defines a url and template members, just access them with their simple name, and not by prefixing like you do this.url and this.template

like image 174
Raffaele Avatar answered Oct 14 '22 07:10

Raffaele