在公司的数据中心项目里使用了Feign,进行接口的调用,在返回一个复杂的对象时候,出现下面的一个错误:
java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to xxx
大致意思就是 LinkedHashMap 不能够转换成 xxx 对象,我很奇怪!因为这个接口相关的地方都没有使用到 LinkedHashMap,他是从哪里冒出来的?我开始调试下面的代码:
@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,用它来接返回的结果!!!
最后更新于 2018-09-03 16:24:26 并被添加「java feign spring cloud」标签,已有 4 位童鞋阅读过。