一般我们在用feign调用接口的时候,如果服务提供方出现了异常,那么调用方一般会显示
feign.FeignException$BadRequest: status400 reading
不考虑服务方宕机的情况,一般有异常都会抛出对应的信息,但是一般情况调用方是无法获取的。通过测试我们发现,如果打印日志的话,是可以看到服务提供方抛出的日志,但是调用方捕获不了,只会报400异常。
所以如果要进行异常传递,我们可以有两种方式,但大部分是需要调用方做调整。
一、fallbackFactory
fallbackFactory就和标准的熔断降级差不多,可以把异常信息全部带过来,但是需要我们对异常做转换,常规的exception还是无法获取body部分的。所以这里我们用FeignException强转,问题就迎刃而解了。
看,我们可以获取到服务端抛出的自定义错误了。
这时候再把json转bean就可以了。
参考:
服务端和客户端共同
@FeignClient(value="sq-service", path="/service",url="http://localhost:9980", fallbackFactory=TestFactory.class)publicinterfaceTestApi{@PostMapping("/test")Stringtest();}
@ComponentpublicclassTestFactoryimplementsFallbackFactory<TestApi>{@OverridepublicTestApicreate(finalThrowable throwable){FeignException ex=(FeignException) throwable;JSONObject jsonObject=JSONObject.parseObject(ex.contentUTF8());returnnewTestApi(){@OverridepublicStringtest(){return jsonObject.getString("message");}};}}
注意!客户端要熔断降级必须在yaml文件里进行配置:
客户端:
feign:
hystrix:
enabled:true
否则无法进入fallbackFactory
二、一劳永逸,全局配置
我直接一个config文件解决!
比起fallbackFactory,不需要共同代码,不需要熔断降级,服务端不需要做任何改动,只需要客户端配置就行。能不改服务端就尽量别动,不然真就,想diss了。
客户端
@ConfigurationpublicclassFeignErrorDecoderimplementsErrorDecoder{@OverridepublicExceptiondecode(finalString methodKey,finalResponse response){try{String message=Util.toString(response.body().asReader());try{JSONObject jsonObject=JSONObject.parseObject(message);// 包装成自己自定义的异常,这里建议根据自己的代码改returnnewMyException(jsonObject.getString("message"), jsonObject.getInteger("code"));}catch(JSONException e){
e.printStackTrace();}}catch(IOException ignored){}returndecode(methodKey, response);}}
可以看到,这种方式可以直接反馈到调用方,也就是说,前端调用都能直接显示在web页面上了。可以说是很直接的告诉你异常了。
feign的异常传递就这么简单,一般来说项目都有自己的自定义异常全局类,仅供参考。
强烈建议全局处理!!!