带有 Spring RESTTemplate 的泛型

Posted

技术标签:

【中文标题】带有 Spring RESTTemplate 的泛型【英文标题】:Generics with Spring RESTTemplate 【发布时间】:2011-12-27 21:02:12 【问题描述】:

我有这样的课:

public class Wrapper<T> 

 private String message;
 private T data;

 public String getMessage() 
    return message;
 

 public void setMessage(String message) 
    this.message = message;
 

 public T getData() 
    return data;
 

 public void setData(T data) 
    this.data = data;
 


我使用resttemplate如下:

...
Wrapper<Model> response = restTemplate.getForObject(URL, Wrapper.class, myMap);
Model model = response.getData();
...

但是它抛出一个:

ClassCastException

我读到:Issue when trying to use Jackson in java 但没有帮助。有一些与我的问题等相关的主题:https://jira.springsource.org/browse/SPR-7002 和https://jira.springsource.org/browse/SPR-7023

有什么想法吗?

PS:我的错误是:

java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to a.b.c.d.Model

我认为resttemplate无法理解我的泛型变量,也许它接受它作为一个对象而不是泛型T。所以它变成了一个LinkedHashMap。您可以从中阅读here 它说,在解释它的编组时:

JSON 类型 | Java类型

对象 | LinkedHashMap

【问题讨论】:

请把异常跟踪也放上去。 我想这个解决方案是在 3.2 SPR-7023 您找到解决方案了吗?我正在使用 ParameterizedTypeReference,虽然它在我传入 Map 时有效,但当我传入代表模型中 data 的具体类时它不起作用。 您找到解决方案了吗?? 【参考方案1】:

ParameterizedTypeReference 已在 3.2 M2 中引入以解决此问题。

Wrapper<Model> response = restClient.exchange(loginUrl, 
                          HttpMethod.GET, 
                          null, 
                          new ParameterizedTypeReference<Wrapper<Model>>() ).getBody();

但是,没有引入 postForObject/getForObject 变体。

【讨论】:

我为你们尝试了另一个选项,@alexanoid。只需首先获得String 的响应,然后使用Jackson 将字符串解析为泛型对象,请参阅:String body = restTemplate.exchange(request,String.class).getBody(); ObjectMapper mapper=new ObjectMapper(); DataTablesOutput&lt;EmployeeResponse&gt; readValue = mapper.readValue(body, DataTablesOutput.class); 为什么这里的 Model 不能也是泛型的?等等这样的:Model&lt;InnerModel&gt; 为了补充 Alter 的答案,您可以使用:mapper.readValue(body, new TypeReference&lt;Wrapper&lt;Model&gt;&gt;()); 我的问题也是为什么我们不能在这里使模型也通用?【参考方案2】:

我认为你唯一能做的就是创建一个扩展 Wrapper 并将模型用作泛型的新类。

class WrapperWithModel extends Wrapper<Model>;

WrapperWithModel response = restTemplate.getForObject(URL, WrapperWithModel.class);

这不是最好的解决方案,但至少您不必手动解组响应。

【讨论】:

我个人不喜欢这个解决方案,但现在我无法升级 spring 以使用它的新参数化类型对象 (jira.springsource.org/browse/SPR-7023),所以这已经足够了。谢谢 必须是静态类【参考方案3】:

不要在 RestTemplate 中使用泛型。使用将隐藏泛型的包装器对象包装请求和响应对象。

【讨论】:

以上是关于带有 Spring RESTTemplate 的泛型的主要内容,如果未能解决你的问题,请参考以下文章

Spring RestTemplate 调用带有错误的 web 服务并分析状态码

如何为 Spring RestTemplate 设置要信任的证书

Spring WebClient与RestTemplate性能对比——响应式Spring的道法

spring RestTemplate提交json格式数据

Spring WebClient vs. RestTemplate

Spring的RestTemplate