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



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

我需要一个要求,当下游服务端点之一返回400(部分成功方案(时,我们的服务需要将其转换为200个成功的响应值。

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

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

您需要创建一个自定义的Client来足够尽早拦截Response以更改响应状态,而不是调用ErrorDecoder。最简单的方法是在现有客户端上创建包装器,并创建具有200状态的新Response。这是使用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;
   }
}

该自定义客户端可用于您需要的任何假装客户端。

另一种做法是在错误解码器上抛出自定义异常,然后将此自定义转换为Spring Global Exception Handler(使用@RestControllerRadvice(

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();
    }
}

更改微服务响应:

public class CustomFeignClient extends Client.Default {
  public CustomFeignClient(
    final SSLSocketFactory sslContextFactory, final HostnameVerifier 
        hostnameVerifier) {
    super(sslContextFactory, hostnameVerifier);
  }
  @Override
  public Response execute(final Request request, final Request.Options 
    options) throws IOException {
    Response response = super.execute(request, options);
    if (HttpStatus.SC_OK != response.status()) {
      response =
        Response.builder()
          .status(HttpStatus.SC_OK)
          .body(InputStream.nullInputStream(), 0)
          .headers(response.headers())
          .request(response.request())
          .build();
    }
    return response;
  }
}

添加假句client:

@Configuration
public class FeignClientConfig {
  @Bean
  public Client client() {
    return new CustomFeignClient(null, null);
  }
}

最新更新