要在Spring RestTemplate中使用泛型类型,我们需要使用ParameterizedTypeReference(无法获得泛型ResponseEntity <T>,其中T是泛型类“ SomeClass <SomeGenericType>”)
Spring RestTemplate
ParameterizedTypeReference
ResponseEntity <T>
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;} }
因此,如果我尝试执行此类操作,则一切正常。
public ResponseWrapper<MyClass> makeRequest(URI uri) { ResponseEntity<ResponseWrapper<MyClass>> response = template.exchange( uri, HttpMethod.POST, null, new ParameterizedTypeReference<ResponseWrapper<MyClass>>() {}); return response; }
但是当我尝试创建上述方法的通用变体时…
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; }
…并像这样调用此方法…
makeRequest(uri, MyClass.class)
…而不是得到ResponseEntity<ResponseWrapper<MyClass>>对象,我得到了ResponseEntity<ResponseWrapper<LinkedHashSet>>对象。
ResponseEntity<ResponseWrapper<MyClass>>
ResponseEntity<ResponseWrapper<LinkedHashSet>>
我怎么解决这个问题?它是RestTemplate错误吗?
我了解这个概念。不幸的是我是在这里新注册的,所以我无法评论他的答案,所以在这里写下。林不知道,我清楚地了解如何实现所提出的方法来解决我的问题与Map使用Class密钥(由@Sotirios在他的回答最后提出)。有人愿意举一个例子吗?
不,这不是错误。这是ParameterizedTypeReference黑客工作方式的结果。
如果看一下它的实现,它会使用Class#getGenericSuperclass()哪些状态
Class#getGenericSuperclass()
返回表示该类表示的实体的直接超类的Type(class, interface, primitive type or void)。
如果超类是参数化类型,则Type返回的对象必须准确反映源代码中使用的实际类型参数。
所以,如果你使用
new ParameterizedTypeReference<ResponseWrapper<MyClass>>() {}
它将准确地返回Typefor ResponseWrapper<MyClass>。
Typefor ResponseWrapper<MyClass>
如果你使用
new ParameterizedTypeReference<ResponseWrapper<T>>() {}
它会准确地返回Typefor,ResponseWrapper<T>因为那是它在源代码中的样子。
Type
ResponseWrapper<T>
当Spring看到T实际上是一个TypeVariable对象时,它不知道要使用的类型,因此它使用其默认值。
TypeVariable
你不能使用ParameterizedTypeReference提议的方式,就接受任何类型的意义而言,使其成为通用的。考虑编写映射到该类的预定义Map键的with键。ClassParameterizedTypeReference
ClassParameterizedTypeReference
你也可以继承ParameterizedTypeReference并覆盖其getType方法返回一个适当的创建ParameterizedType,通过IonSpin的建议。
getType
ParameterizedType