Feign调用返回复杂对象时报错java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to xxx

在公司的数据中心项目里使用了Feign,进行接口的调用,在返回一个复杂的对象时候,出现下面的一个错误:

1
java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to xxx

大致意思就是 LinkedHashMap 不能够转换成 xxx 对象,我很奇怪!因为这个接口相关的地方都没有使用到 LinkedHashMap,他是从哪里冒出来的?我开始调试下面的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
@Override
public List<EsFilterKV> getFilterKV(Integer companyId, Integer appId, Long usrId, String filterName) {

if (StringUtils.isEmpty(filterName)){
return null;
}

List<CompanyDistributionFilterGroup> distributionFilterGroupList = companyDistributionService.findDistributionFilterGroupList(companyId,true);

List<ProductDocument> productDocumentList = new ArrayList<ProductDocument>(100);
try {
for (CompanyDistributionFilterGroup group: distributionFilterGroupList) {
List<FilterItem> filterItemList = filterGroupFilterService.findFilterItemList(group.getFilterGroupId());
MtSearchFilterRequest request = new MtSearchFilterRequest();
request.setFilterItemList(filterItemList);
MtSearchResult mtSearchResult = productSearchService.search(request);
productDocumentList.addAll(mtSearchResult.getData());
}
} catch (MtException e) {
e.printStackTrace();
}

List<Long> longList = productDocumentList.stream().map(p->p.getId()).distinct().collect(Collectors.toList());
if (CollectionUtils.isEmpty(longList)){
return null;
}
List<Map> idValueList = productPackageService.findPackageIdValueList(longList,filterName,true);

if (CollectionUtils.isEmpty(idValueList)){
return null;
}

List<EsFilterKV> esFilterKVs = new ArrayList<EsFilterKV>(idValueList.size());

for (Map map: idValueList){
EsFilterKV esFilterKV = new EsFilterKV();

esFilterKV.setName(map.get("name").toString());
esFilterKV.setId(new Long(map.get("id").toString()));
esFilterKV.setJsonName("{'id':"+esFilterKV.getId()+",'name':'"+esFilterKV.getName()+"'}");

esFilterKVs.add(esFilterKV);
}

return esFilterKVs;
}

我发现在 productDocumentList.addAll(mtSearchResult.getData()); 这一行,productDocumentList里面放的全是LinkedHashMap,不是想象中的对象列表。通过面向百度编程,我把productSearchService.search()这个方法返回的泛型给去掉了,指定了真实的类型,从而解决了上面的问题!

通过百度得知有不少人遇到这种问题,有个感觉比较靠谱的解释如下:

因为rpc远程调用在底层还是使用的HTTPClient,所以在传递参数的时候,必定要有个顺序,当你传递map的时候map里面的值也要有顺序,不然服务层在接的时候就出问题了,所以它才会从map转为linkedhashMap!spring 有一个类叫ModelMap,继承了linkedhashMap public class ModelMap extends LinkedHashMap ,所以一个接口返回的结果就可以直接用ModelMap来接,注意ModelMap是没有泛型的,不管你返回的结果是什么类型的map,泛型是多复杂的map,都可以直接new一个Modelmap,用它来接返回的结果!!!

  • 作者: Sam
  • 发布时间: 2018-09-30 23:39:50
  • 最后更新: 2019-12-09 23:03:26
  • 文章链接: https://ydstudios.gitee.io/post/4f6a533b.html
  • 版权声明: 本网所有文章除特别声明外, 禁止未经授权转载,违者依法追究相关法律责任!