Spring RESTTemplate的泛型


72

我有这样的课:

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

我读到:尝试在Java中使用Jackson时出现问题,但没有帮助。有一些与我的问题等相关的主题: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无法理解我的通用变量,也许它将它接受为Object而不是通用T。因此它变成了LinkedHashMap。您可以在这里阅读它说,当解释从编组到什么时:

JSON类型| Java类型

对象 LinkedHashMap


Plz也放置了异常跟踪。
桑托什

我此假设溶液中加入3.2 SPR-7023
raksja

您是否找到了解决方案?我正在使用ParameterizedTypeReference,当我传递Map <String,String>时它可以工作,而当我传递代表data您的模型的具体类时,它不起作用。
danieljimenez 2014年

您找到解决方案了吗?
Prasanna Kumar HA

Answers:


137

在3.2 M2中引入了ParameterizedTypeReference来解决此问题。

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

但是,未引入postForObject / getForObject变体。


1
我尝试了另一个供您选择的选项,@ alexanoid。刚获得响应为String,然后使用Jackson将字符串解析为泛型对象,请参见: String body = restTemplate.exchange(request,String.class).getBody(); ObjectMapper mapper=new ObjectMapper(); DataTablesOutput<EmployeeResponse> readValue = mapper.readValue(body, DataTablesOutput.class);
Alter Hu

1
为什么模型在这里也不能通用?等等,像这样:Model<InnerModel>
zygimantus

为了补充Alter的答案,您可以使用:mapper.readValue(body, new TypeReference<Wrapper<Model>>(){});
cs94njw

我的问题也是为什么我们在这里不能使Model也通用?
u91

8

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

class WrapperWithModel extends Wrapper<Model>{};

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

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


我个人不喜欢这种解决方案,但是现在我无法升级spring以使用其新的parameterizedtype对象(jira.springsource.org/browse/SPR-7023),所以这足够好了。谢谢
Gustavo Matias

它必须是静态课程
Adam Silenko

4

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


-1
        ResponseEntity<Result>
                response = restTemplate.postForEntity("/user", user, Result.class);

        ObjectMapper objectMapper=new ObjectMapper();
        String content = objectMapper.writeValueAsString(response.getBody().getData());
        User user1 = objectMapper.readValue(content, User.class);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.