java - 在具有泛型参数的泛型方法中使用 Spring RestTemplate

标签 java spring generics jackson 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,我理解了这个概念。不幸的是,我刚在这里注册,所以我无法评论他的答案,所以在这里写。我不确定我是否清楚地了解如何实现建议的方法来解决我的问题 MapClass关键(由@Sotirios 在他的回答末尾提出)。有人介意举个例子吗?

最佳答案

不,这不是错误。这是 ParameterizedTypeReference 的结果黑客作品。

如果您查看它的实现,它使用 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>>() {}

它将准确地返回 Type对于 ResponseWrapper<MyClass> .

如果你使用

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

它将准确地返回 Type对于 ResponseWrapper<T>因为这就是它在源代码中的显示方式。

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

您不能使用 ParameterizedTypeReference您提出的方式,使其在接受任何类型的意义上具有通用性。考虑写一个Map带 key Class映射到预定义的 ParameterizedTypeReference为那个类(class)。

你可以继承 ParameterizedTypeReference并覆盖其getType方法返回一个适当创建的 ParameterizedType , as suggested by IonSpin .

关于java - 在具有泛型参数的泛型方法中使用 Spring RestTemplate,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21987295/

相关文章:

java - 如何在 Java 中获取 Javascript var 值 (wicket 6)

java - 带有可迭代的 Spring 数据 findAllBy 返回空数组

java - Spring `SavedRequest` 是否包含任何清理逻辑以避免重定向循环或类似循环?

delphi - 如何使用泛型方法和<T>数组的参数数组?

c# - 在泛型类 <T,U> 的方法中比较 T 的两个变量(从 C++ 到 C# 的代码移植)

java - 如何在 Java 中使用数组进行类型泛型?

java - 停止 servlet 响应

java - 有没有办法执行java中已经执行的代码

java - Wicket 口,返回上一页

ajax - 如何将参数传递给 Thymeleaf Ajax 片段