近期在使用Feign开发调用其他系统的微服务接口的时候遇到了需求,需要把原来系统抛出来的状态码和异常捕捉以及原样抛出。由于使用了Hystrix熔断,发现Feign返回的异常和原来抛出的不一致,故在此做个解决记录
解决方案:
一、自定义全局异常配置
@ConfigurationpublicclassFeignGlobalConfig{@BeanErrorDecoderresponseErrorDecoder(){// 调用异常处理returnnewDefaultErrorDecoder();}}
二、自定义FeignBadRequestException
publicclassFeignBadRequestExceptionextendsHystrixBadRequestException{privateint code;publicFeignBadRequestException(int code,String message){super(message);this.code= code;}publicintgetCode(){return code;}}
三、重写ErrorDecoder解码器
publicclassDefaultErrorDecoderimplementsErrorDecoder{@OverridepublicExceptiondecode(String s,Response response){Exception exception=null;String bodyStr=null;try{
bodyStr=Util.toString(response.body().asReader());}catch(IOException e){
e.printStackTrace();}//除了200的其余异常走FeignBadRequestExceptionif(response.status()!=200){returnnewFeignBadRequestException(response.status(), bodyStr);}returnnewRuntimeException(bodyStr);}
四、编写异常处理
publicclassRestApiExceptionHandlerextendsResponseEntityExceptionHandler{@ExceptionHandler(value={FeignBadRequestException.class})publicResponseEntity<Object>handleFeignException(FeignBadRequestException ex,WebRequest request){
log.error("Feign Bad Request Error: ", ex);returnhandleExceptionInternal(ex,buildFeignResponse(newFeignBadRequestException(ex.getCode(), ex.getMessage())),newHttpHeaders(),HttpStatus.valueOf(ex.getCode()), request);}privateStringbuildFeignResponse(FeignBadRequestException ae){return ae.getMessage();}}