java – 在通用参数的泛型方法中使用Spring RestTemplate

要使用Spring RestTemplate的泛型类型,我们需要使用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;}
}

所以如果我想做这样的事情,一切都行。

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>>目的。

如何解决这个问题?是否是RestTemplate错误?

更新1
感谢@Sotirios我理解这个概念。不幸的是,我刚刚在这里注册,所以我不能评论他的答案,所以写在这里。我不知道我清楚地了解如何实施提出的方法来解决我的问题与地图与类密钥(由@Sotirios在他的答案结尾提出)。有人会想起一个例子吗?

最佳答案
不,这不是一个bug。这是ParameterizedTypeReference hack如何工作的结果。

如果你看它的实现,它使用Class#getGenericSuperclass()

Returns the Type representing the direct superclass of the entity
(class, interface, primitive type or void) represented by this Class.

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< MyClass>的类型。

如果你使用

new ParameterizedTypeReference<ResponseWrapper<T>>() {}

它将准确地返回ResponseWrapper的类型< T>因为这是它在源代码中的出现。

当Spring看到T,这实际上是一个TypeVariable对象时,它不知道要使用的类型,所以它使用它的默认值。

您不能以您提出的方式使用ParameterizedTypeReference,使其在接受任何类型的意义上是通用的。考虑编写一个映射关系类映射到该类的一个预定义的ParameterizedTypeReference。

转载注明原文:java – 在通用参数的泛型方法中使用Spring RestTemplate - 代码日志