利用feign调用返回object类型转换成实体

目录
  • feign调用返回object转成实体
  • feign调用报类型转换错误
    • 问题现象
    • 排查过程
    • 问题原因
    • 解决办法

feign调用返回object转成实体

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.9.8</version>
</dependency>
ObjectMapper mapper=new ObjectMapper();
CourseMaster courseMaster = mapper.convertValue(bean,CourseMaster.class);
List<CourseMaster> list=(List<CourseMaster>)courseMasterList;//返回为Object类型
for(Object cs:list){
    CourseMaster courseMaster = mapper.convertValue(cs,CourseMaster.class);
}

feign调用报类型转换错误

问题现象

springcloud feign服务间调用,运行至下图1代码A处报错:

java.util.LinkedHashMap cannot be cast to(报错如下图2所示)

排查过程

step1:大多数情况下,第一反应是仔细检查语法是否有问题,确认lambda表达式本身没有问题;

step2:在确认写的没有问题的情况下,将代码片段拎出来写一个main方法运行(如图1代码片段B),发现单独拿出来在main方法中运行时正常!

step3:此时陷入困惑,于是重新仔细阅读报错信息:LinkedHashMap cannot be cast to xxx.BaseComapny,可以很清楚的确定是类型转换错误。

再一行一行看代码(图1中代码片段A),发现只有在代码片段A上方的:List list = xxxxx这一段中有可能的类型转换,所以暂时定位至此行代码。

step4:step3中的推测不确定的原因在于:此行代码中responseObject是直接通过服务调用获取到的,请求响应参数中已指定了对象类型,所以我认为这里不存在强制类型转换,也不存在LinkedHashMap。

继续沿着上面的推测,如果确实存在问题,那只可能是通过服务调用获取到的返回参数与预期不一致,step5:于是分别对上面图1中代码A和代码B(也就是main方法)做debug,结果如下图所示,发现确实服务调用后获取的响应参数与main方法中的不一致。可以看到片段A服务调用得到的响应参数list中确实是LinkedHashMap!至此发现问题!

step6:由于确定自己没有对服务调用前后特殊处理过响应参数,所以考虑这是框架行为,至此问题基本找到原因。

问题原因

找出原因后再针对性的百度答案就比较容易得到,简单来说就是使用feign进行远程服务调用的时候,返回参数(在我的代码中,Response中的list部分)会变成LinkedHashMap。

以下是网上能找到的流传最多的解释(因为复制这段话的文章和博客太多了,无法确认谁复制了谁,也无法确认第一个写的作者是谁,所以无法标注出原作者):

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

解决办法

1、最简单的解决办法就是在接收响应参数的地方直接用LinkedHashMap接收,通过kv形式获取到参数;

2、通过json,objectmapper等方式将LinkedHashMap转换成自己想要的对象;

3、对feign调用得到的响应参数做自定义处理(也许可以?);

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • 解决feignClient调用时获取返回对象类型匹配的问题

    feignClient调用时获取返回对象类型匹配 feignClient是springCloud体系中重要的一个组件,用于微服务之间的相互调用,底层为httpClient,在之前的应用中,我一直以为A服务提供的方法返回类型为对象的话,那么调用A服务的B服务必须也用字段类型以及命名完全相同的对象来接收,为此我验证了一下,发现不是必须用完全相同的对象来接收,比如,可以用map<String,Object>或者Object来接收,然后解析. 当然,复杂对象我还是推荐用一个完全相同的对象来接收. 下面

  • 解决feign接口返回泛型设置属性为null的问题

    简介 feign是一种声明式http请求调用方式,工作原理就是根据FeignClient注解生成新的接口(也就是传说中的动态代理),常见使用方式如下所示: @FeignClient(name="UserFeignService",url="${auth.url}", fallbackFactory = OrgFeignServiceFallback.class, configuration = FeignErrorDecoderConfiguration.class

  • feign调用返回object类型转换方式

    feign调用返回object类型转换 引入依赖 <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.9.8</version> </dependency> /** * @Description: 将数据转换到相应的容器 * @param b

  • 利用feign调用返回object类型转换成实体

    目录 feign调用返回object转成实体 feign调用报类型转换错误 问题现象 排查过程 问题原因 解决办法 feign调用返回object转成实体 <dependency>     <groupId>com.fasterxml.jackson.core</groupId>     <artifactId>jackson-databind</artifactId>     <version>2.9.8</version&g

  • Java利用反射自动封装成实体对象的方法

    本文实例讲述了Java利用反射自动封装成实体对象的方法.分享给大家供大家参考.具体分析如下: 利用此方法的时候需要传递的参数的名称,必须以行号结尾,去掉行号就是属性名称,比如页面传递name+rowNo,那么实体对象的属性名应该为name.代码如下 复制代码 代码如下: //获取页面数据,自动封装成bean对象 public List getObjectList(Class clazz,String[] rowNos) throws Exception{         List objList

  • 如何自定义feign调用实现hystrix超时、异常熔断

    需求描述 spring cloud 项目中feign 整合 hystrix经常使用,但是最近发现hystrix功能强大,但是对我们来说有些大材小用. 首先我只需要他的一个熔断作用,就是说请求超时.异常了返回 FeignClient注解中配置的fallback,不需要非阻塞操作.也不需要重试,hystrix 调用feign时候做了线程池隔离处理,这样增加了项目复杂度(线程池参数配置.线程少了请求服务直接拒绝,多了线程得管理...) 目前feign 超时之后是直接抛异常的,这样的话虽然是及时熔断了,

  • JavaScript中的object转换成number或string规则介绍

    在JavaScript程序编写过程中,根据不同的上下文,JS会自动将object转换成number或者string后再处理.这种自动转换的规则如下: object自动转换成string的规则: 1.如果object所属类覆写了toString()方法,则调用该方法.如果toString()调用的返回结果为Primitive(string.number.boolean.undefined.null),则将该Primitive值转换成string后返回. 2.如果object所属类没有覆写toStr

  • Java List Object[]转换成List T的实例

    一)背景 主要是为了实现数据之间的转换,方便数据展示. 使用场景:当数据可能是List<Object[]>类型,可能会需要转换成具体的List<Class>格式. 二)List<Object[]>转换成List<T> 功能:传入List<Object[]>数据和需要转换的Class对象,返回一个List<Class>数据集合 实现方式:Java反射方式,使用的是构造器的方式 缺点:实体类中必须有无参数构造器,有参数构造器,且构造器参数

  • 将HTML的左右尖括号等转义成实体形式的两种实现方式

    前端开发工作中,经常需要将HTML的左右尖括号等转义成实体形式.我们不能把<,>,&等直接显示在最终看到的网页里.需要将其转义后才能在网页上显示. 转义字符(Escape Sequence)也称字符实体(Character Entity).定义转义字符串的主要原因是 "<"和">"等符号已经用来表示HTML TAG,因此不能直接当作文本中的符号来使用.但有时需求是在HTML页面上使用这些符号,所以需要定义它的转义字符串. 有些字符在A

  • Feign调用接口解决处理内部异常的问题

    问题描述: 当使用feign调用接口,出现400-500-的接口问题时.会出错feign:FeignException.(因为是错误,只能用catch Throwable,不可使用catch Exception捕获异常)导致程序无法继续运行. 问题原因: 由于feign默认的错误处理类是FunFeignFallback会throw new AfsBaseExceptio导致外部无法捕获异常. package com.ruicar.afs.cloud.common.core.feign; impo

  • Feign调用服务各种坑的处理方案

    1.编写被调用服务 @RefreshScope @RestController public class XXXController extends BaseController implements IndicatorsFeignApi{ @Resource private XXXService xxx; @Override public Wrapper<CommonVo> getXXXX(@RequestBody CommonDto commonDto) { try { CommonVo

随机推荐