虚假客户端错误处理-抑制错误/异常并转换为200成功响应

时间:2019-05-15 22:26:04

标签: java spring-boot spring-cloud-feign netflix-feign feign

我正在使用伪装客户端连接到下游服务。

我有一个要求,当下游服务端点之一返回400(这是部分成功的情况)时,我们的服务需要将此响应值转换为200成功。

我正在寻找一种最佳的方法。

我们正在使用错误解码器来处理错误,并且上面的转换仅适用于一个端点,而不适用于所有下游端点,并注意到decode()方法应返回异常。

2 个答案:

答案 0 :(得分:0)

您将需要创建自定义的Client来尽早拦截Response,以更改响应状态并且不调用ErrorDecoder。最简单的方法是在现有客户端上创建包装器,然后创建状态为Response的新200。这是使用Feign的ApacheHttpClient时的示例:

public class ClientWrapper extends ApacheHttpClient {
   private ApacheHttpClient delegate;

   public ClientWrapper(ApacheHttpClient client) {
      this.client = client;
   }

   @Override
   public Response execute(Request request, Request.Options options) throws IOException {
      /* execute the request on the delegate */
      Response response = this.client.execute(request, options);

      /* check the response code and change */
      if (response.status() == 400) {
         response = Response.builder(response).status(200).build();
      }
      return response;
   }
}

此定制的客户端可用于您需要的任何Feign客户端。

答案 1 :(得分:0)

另一种方法是在错误解码器上抛出自定义异常,然后在spring全局异常处理程序(使用@RestControllerAdvice)中将此自定义异常转换为成功

public class CustomErrorDecoder implements ErrorDecoder {

@Override
public Exception decode(String methodKey, Response response) {

    if (response.status() == 400 && response.request().url().contains("/wanttocovert400to200/clientendpoints") {
        ResponseData responseData;
        ObjectMapper mapper = new ObjectMapper();
        try {
            responseData = mapper.readValue(response.body().asInputStream(), ResponseData.class);
        } catch (Exception e) {
            responseData = new ResponseData();
        }
        return new PartialSuccessException(responseData); 
    }
    return FeignException.errorStatus(methodKey, response);
}}

以及如下所示的异常处理程序

@RestControllerAdvice
public class GlobalControllerExceptionHandler {

    @ResponseStatus(HttpStatus.OK)
    @ExceptionHandler(PartialSuccessException.class)
    public ResponseData handlePartialSuccessException(
            PartialSuccessException ex) {
        return ex.getResponseData();
    }
}