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

在公司的数据中心项目里使用了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,用它来接返回的结果!!!

相关文章

此处评论已关闭