【问题标题】:Generics with Spring RESTTemplate带有 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-7002https://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 的具体类时它不起作用。
  • 您找到解决方案了吗??

标签: java spring generics jackson resttemplate


【解决方案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 中使用泛型。使用将隐藏泛型的包装器对象包装请求和响应对象。

【讨论】:

    猜你喜欢
    • 2014-03-26
    • 2016-08-23
    • 2016-04-11
    • 2018-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多