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
Unable to get a generic ResponseEntity<T> where T is a generic class "SomeClass<SomeGenericType>"
提问by IgorA
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
请帮我得到一个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 url
and template
members, just access them with their simple name, and not by prefixing like you do this.url
and this.template
顺便说一句,在 Java 中,您不需要使用前缀访问实例变量this
:如果您的对象定义了 aurl
和template
成员,只需使用它们的简单名称访问它们,而不是像您那样通过前缀访问this.url
和this.template