Unable to get a generic ResponseEntity<T> where T is a generic class "SomeClass<SomeGenericType>"
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
IgorA
I am very interested in various aspects of software engineering, web architecture and all things Java related!
Updated on June 07, 2022Comments
-
IgorA almost 2 years
Please help me to get a
ResponseEntity<T>
whereT
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.2Here 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 notpostForEntity()
:CisResponse<CisResponseEntity> response = this.restTemplate.postForObject( this.rootURL,myRequestObj, CisResponse.class);