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

19,762

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

Share:
19,762
IgorA
Author by

IgorA

I am very interested in various aspects of software engineering, web architecture and all things Java related!

Updated on June 07, 2022

Comments

  • IgorA
    IgorA almost 2 years

    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);