关于java:Spring RESTTemplate的泛型

Generics with Spring RESTTemplate

我有这样的课:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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如下:

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

但是它抛出:

我读到:尝试在Java中使用Jackson时出现问题,但没有帮助。 有一些与我的问题等相关的主题:https://jira.springsource.org/browse/SPR-7002和https://jira.springsource.org/browse/SPR-7023

有任何想法吗?

PS:我的错误是:

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

我认为resttemplate无法理解我的通用变量,也许它将它接受为Object而不是通用T。因此它变成了LinkedHashMap。 您可以在这里阅读它说,当解释从编组到什么时:

JSON Type | Java Type

object | LinkedHashMap


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

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

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


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

1
2
3
class WrapperWithModel extends Wrapper<Model>{};

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

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


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


1
2
3
4
5
6
        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);