我正在使用Netflix Feign调用微服务A的一个操作,调用微服务B的其他其他操作,该操作使用Spring Boot验证代码。
如果验证不正确,微服务B的操作将引发异常。然后,我在微服务中进行处理,并返回如下所示的HttpStatus.UNPROCESSABLE_ENTITY(422):
HttpStatus.UNPROCESSABLE_ENTITY
@ExceptionHandler({ ValidateException.class }) @ResponseStatus(HttpStatus.UNPROCESSABLE_ENTITY) @ResponseBody public Object validationException(final HttpServletRequest request, final validateException exception) { log.error(exception.getMessage(), exception); error.setErrorMessage(exception.getMessage()); error.setErrorCode(exception.getCode().toString()); return error; }
因此,当微服务A接下来在接口中调用B时:
@Headers("Content-Type: " + MediaType.APPLICATION_JSON_UTF8_VALUE) @RequestLine("GET /other") void otherOperation(@Param("other") String other ); @Headers("Content-Type: " + MediaType.APPLICATION_JSON_UTF8_VALUE) @RequestLine("GET /code/validate") Boolean validate(@Param("prefix") String prefix); static PromotionClient connect() { return Feign.builder() .encoder(new GsonEncoder()) .decoder(new GsonDecoder()) .target(PromotionClient.class, Urls.SERVICE_URL.toString()); }
并且验证失败它返回内部错误500和下一条消息:
{ "timestamp": "2016-08-05T09:17:49.939+0000", "status": 500, "error": "Internal Server Error", "exception": "feign.FeignException", "message": "status 422 reading Client#validate(String); content:\n{\r\n \"errorCode\" : \"VALIDATION_EXISTS\",\r\n \"errorMessage\" : \"Code already exists.\"\r\n}", "path": "/code/validate" }
但是我需要返回与微服务操作B相同的结果。
Wich是使用Netflix Feign通过微服务传播状态和异常的最佳方法或技术吗?
你可以假装 ErrorDecoder
ErrorDecoder
https://github.com/OpenFeign/feign/wiki/Custom-error- handling
这是一个例子
public class MyErrorDecoder implements ErrorDecoder { private final ErrorDecoder defaultErrorDecoder = new Default(); @Override public Exception decode(String methodKey, Response response) { if (response.status() >= 400 && response.status() <= 499) { return new MyBadRequestException(); } return defaultErrorDecoder.decode(methodKey, response); } }
为了让Spring能够使用ErrorDecoder,必须将其放在ApplicationContext上:
@Bean public MyErrorDecoder myErrorDecoder() { return new MyErrorDecoder(); }