ClassCastException:RestTemplate返回的是List<LinkedHashMap>而不是List<MymodelClass>。

50
我正在尝试访问我的 MyModelClass 上的 getter 方法,但是我的代码返回的是 List 而不是 List。这是我的代码。
List<MyModelClass> myModelClass = 
   (List<MyModelClass>) restTemplate.postForObject(url,mvm,List.class);

System.out.println("Response= " +  myModelClass);

我尝试打印响应,得到了我期望的JSON响应。 但是当我尝试运行这段代码时。
System.out.println("Response= " +  myModelClass.get(0).getMessage());

它会产生这个错误。
java.lang.ClassCastException: 
java.util.LinkedHashMap cannot be cast to com.XXX.XXX.MyModelClass 

这是不匹配的。有人能帮我解决这个错误吗?谢谢。

我的模型类

public class MyModelClass{
        
    /**
     * 
     */
    @JsonProperty("id")
    public String id;
    
    @JsonProperty("type")
    public String type;
    
    @JsonProperty("user")
    public String user;
    
    @JsonProperty("message")
    public String message;

    //getters

错误的原因

MyModelClass[] myModelClass= restTemplate.postForObject(url,mvm, myModelClass[].class);

org.springframework.http.converter.HttpMessageNotReadableException:
Could not read JSON: 
Can not deserialize instance of java.util.ArrayList out of START_OBJECT token

JSON响应结构

    [{"key1":"value1","key2":"value2","parameters":{"key1":"value1","key2":"value2","key3":"value3","key4":"value4","key5":"value5"}},
{"key12":"value12","key22":"value22","parameters":{"key12":"value12","key22":"value22","key32":"value32","key42":"value42","key52":"value52"}}]

如果对于如何在RestTemplate中映射这种类型的JSON响应有任何建议,将会非常有帮助。谢谢。

1
嗨,Erick,你找到解决问题的方法了吗?我也几乎有同样的问题。 - Emilla
1
这个答案帮助我解决了问题。https://dev59.com/rmUp5IYBdhLWcg3wNVhb#15453159 - Deepankar Sarkar
有一些方法可以将List<LinkedHashMap>转换为List<MyModelClass>。但是,当restTemplate返回List<LinkedHashMap>并将其分配给myModelClass[]时,为什么它不会抛出任何异常?它们是不同的类型。为什么? - Robin Sun
2个回答

64

使用以下方法调用

List<MyModelClass> myModelClass=(List<MyModelClass>) restTemplate.postForObject(url,mvm,List.class);

所有的Jackson知道的就是你需要一个List,但没有对类型做出任何限制。默认情况下,Jackson将JSON对象反序列化为LinkedHashMap,这就是为什么你会得到ClassCastException的原因。

如果你返回的是一个数组,那么获取它的一种方式是使用数组

MyModelClass[] myModelClasses = restTemplate.postForObject(url,mvm, MyModelClass[].class);

你可以把那个数组的元素添加到一个List中。

我不记得自从哪个版本开始了,但是RestTemplate#exchange现在有一个重载,接受一个ParameterizedTypeReference参数。 ParameterizedTypeReference 是类型标记 hack,它建议将参数化类型作为反序列化的目标。

您可以重构上面的代码以使用exchange而不是postForObject,并使用ParameterizedTypeReference来获取一个List<MyModelClass>。例如:

ParameterizedTypeReference<List<MyModelClass>> typeRef = new ParameterizedTypeReference<List<MyModelClass>>() {
};
ResponseEntity<List<MyModelClass>> responseEntity = restTemplate.exchange(url, HttpMethod.POST, new HttpEntity<>(mvm), typeRef);
List<MyModelClass> myModelClasses = responseEntity.getBody();

2

通过以下方法调用,您可以将LinkedHashMap转换为List

ObjectMapper mapper = new  ObjectMapper();
List<Object> list = mapper.convertValue(listResponse, new TypeReference<List<Object>>() {})

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接