java 无法获得通用 ResponseEntity<T>,其中 T 是通用类“SomeClass<SomeGenericType>”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13819734/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 14:05:19  来源:igfitidea点击:

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

javaspringrestgenericsspring-mvc

提问by IgorA

Please help me to get a ResponseEntity<T>where Tis 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

请帮我得到一个ResponseEntity<T>whereT本身就是一个泛型类型。正如我现在所见,现在 Spring RestTemplate 不支持此功能。我使用的是 Spring MVC 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():

现在,我使用这个解决方案,postForObject()而不是postForEntity()

CisResponse<CisResponseEntity> response = 
          this.restTemplate.postForObject(
               this.rootURL,myRequestObj, CisResponse.class);

回答by Raffaele

This was a known issue. Now it's fixed with the introduction of ParameterizedTypeReference, which is a parameterized type that you explicitely inheritto 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 supertypeat runtime.

这是一个已知问题。现在它通过引入来修复ParameterizedTypeReference,它是一个参数化类型,您显式继承它以在运行时提供类型信息。这称为超类型标记,并且可以解决类型擦除问题,因为子类(在这种情况下是匿名的)在运行时保留泛型超类型类型参数

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

但是您不能使用postForObject,因为该 API 仅支持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 hacksfor achieving Foo<Bar<Baz>>.class

请注意,最后一行演示了超类型标记的想法:您不提供文字CisResponse.class,而是提供参数化类型的匿名实例化ParameterizedTypeReference<T>,它可以在运行时提取子类型信息。你能想到的超类型令牌作为黑客实现Foo<Bar<Baz>>.class

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

顺便说一句,在 Java 中,您不需要使用前缀访问实例变量this:如果您的对象定义了 aurltemplate成员,只需使用它们的简单名称访问它们,而不是像您那样通过前缀访问this.urlthis.template