我正在使用伪装客户端连接到下游服务。
我有一个要求,当下游服务端点之一返回400(这是部分成功的情况)时,我们的服务需要将此响应值转换为200成功。
我正在寻找一种最佳的方法。
我们正在使用错误解码器来处理错误,并且上面的转换仅适用于一个端点,而不适用于所有下游端点,并注意到decode()方法应返回异常。
答案 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();
}
}