在具有泛型参数的泛型方法中使用 Spring RestTemplate [英] Using Spring RestTemplate in generic method with generic parameter
问题描述
要在 Spring RestTemplate 中使用泛型类型,我们需要使用 ParameterizedTypeReference
(无法获得通用响应实体
To use generic types with Spring RestTemplate we need to use ParameterizedTypeReference
(Unable to get a generic ResponseEntity<T> where T is a generic class "SomeClass<SomeGenericType>")
假设我有一些课程
public class MyClass {
int users[];
public int[] getUsers() { return users; }
public void setUsers(int[] users) {this.users = users;}
}
还有一些包装类
public class ResponseWrapper <T> {
T response;
public T getResponse () { return response; }
public void setResponse(T response) {this.response = response;}
}
所以如果我尝试做这样的事情,一切都很好.
So if I'm trying to do something like this, all is OK.
public ResponseWrapper<MyClass> makeRequest(URI uri) {
ResponseEntity<ResponseWrapper<MyClass>> response = template.exchange(
uri,
HttpMethod.POST,
null,
new ParameterizedTypeReference<ResponseWrapper<MyClass>>() {});
return response;
}
但是当我尝试创建上述方法的通用变体时......
But when I'm trying to create generic variant of the above method ...
public <T> ResponseWrapper<T> makeRequest(URI uri, Class<T> clazz) {
ResponseEntity<ResponseWrapper<T>> response = template.exchange(
uri,
HttpMethod.POST,
null,
new ParameterizedTypeReference<ResponseWrapper<T>>() {});
return response;
}
...并像这样调用这个方法...
... and calling this method like so ...
makeRequest(uri, MyClass.class)
... 而不是获取 ResponseEntity
对象,我得到的是 ResponseEntity
对象.
... instead of getting ResponseEntity<ResponseWrapper<MyClass>>
object I'm getting ResponseEntity<ResponseWrapper<LinkedHashSet>>
object.
我该如何解决这个问题?是 RestTemplate 的错误吗?
How can I solve this problem? Is it a RestTemplate bug?
更新 1感谢@Sotirios,我理解了这个概念.不幸的是,我是在这里新注册的,所以我不能评论他的回答,所以写在这里.我不确定我是否清楚地理解如何使用 Map
和 Class
键(由@Sotirios 在他的回答末尾提出)来实施建议的方法来解决我的问题.有人介意举个例子吗?
UPDATE 1
Thanks to @Sotirios I understand the concept. Unfortunately I'm newly registered here so I cant comment on his answer, so writing it here. Im not sure that I clearly understand how to implement the proposed approach to solve my problem with Map
with Class
key (Proposed by @Sotirios in the end of his answer). Would someone mind to give an example?
推荐答案
不,这不是错误.这是 ParameterizedTypeReference
hack 工作方式的结果.
No, it is not a bug. It is a result of how the ParameterizedTypeReference
hack works.
如果你看看它的实现,它使用 Class#getGenericSuperclass()
说明
If you look at its implementation, it uses Class#getGenericSuperclass()
which states
返回代表实体直接超类的类型(类、接口、原始类型或void)由此类表示.
Returns the Type representing the direct superclass of the entity (class, interface, primitive type or void) represented by this Class.
如果超类是参数化类型,返回的Type
对象必须准确反映源中使用的实际类型参数代码.
If the superclass is a parameterized type, the Type
object returned
must accurately reflect the actual type parameters used in the source
code.
所以,如果你使用
new ParameterizedTypeReference<ResponseWrapper<MyClass>>() {}
它会准确地为 ResponseWrapper
返回一个 Type
.
it will accurately return a Type
for ResponseWrapper<MyClass>
.
如果你使用
new ParameterizedTypeReference<ResponseWrapper<T>>() {}
它会准确地为 ResponseWrapper
返回一个 Type
,因为这就是它在源代码中的显示方式.
it will accurately return a Type
for ResponseWrapper<T>
because that is how it appears in the source code.
当 Spring 看到 T
,它实际上是一个 TypeVariable
对象时,它不知道要使用的类型,所以它使用它的默认值.
When Spring sees T
, which is actually a TypeVariable
object, it doesn't know the type to use, so it uses its default.
您不能按照您提议的方式使用 ParameterizedTypeReference
,使其在接受任何类型的意义上成为通用的.考虑编写一个 Map
,其中键 Class
映射到该类的预定义 ParameterizedTypeReference
.
You cannot use ParameterizedTypeReference
the way you are proposing, making it generic in the sense of accepting any type. Consider writing a Map
with key Class
mapped to a predefined ParameterizedTypeReference
for that class.
您可以子类化 ParameterizedTypeReference
并覆盖其 getType
方法以返回适当创建的 ParameterizedType
,根据 IonSpin 的建议.
You can subclass ParameterizedTypeReference
and override its getType
method to return an appropriately created ParameterizedType
, as suggested by IonSpin.
这篇关于在具有泛型参数的泛型方法中使用 Spring RestTemplate的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!