FeignErrordeCoder检索原始消息
Contents
1. 概述
RESTful 服务可能因多种原因而失败。在本教程中,我们将了解如果集成的 REST 服务抛出错误,如何从Feign客户端检索原始消息 。
2. Feign 客户端
Feign 是一个可插拔的声明式 Web 服务客户端,它使编写 Web 服务客户端变得更加容易。此外,对于 Feign 注解,它还支持JAX-RS ,并且它支持编码器和解码器以提供更多的自定义。
3. 从ErrorDecoder 中检索消息
当发生错误时,Feign 客户端会隐藏原始消息,为了检索它,我们需要编写一个自定义的ErrorDecoder **。如果没有这样的定制,我们会得到以下错误:
feign.FeignException$NotFound: [404] during [POST] to [http://localhost:8080/upload-error-1] [UploadClient#fileUploadError(MultipartFile)]: [{"timestamp":"2022-02-18T13:25:22.083+00:00","status":404,"error":"Not Found","path":"/upload-error-1"}]
at feign.FeignException.clientErrorStatus(FeignException.java:219) ~[feign-core-11.7.jar:na]
at feign.FeignException.errorStatus(FeignException.java:194) ~[feign-core-11.7.jar:na]
为了处理这个错误,我们将创建一个简单的ExceptionMessage Java bean 来表示错误消息:
public class ExceptionMessage {
private String timestamp;
private int status;
private String error;
private String message;
private String path;
// standard getters and setters
}
让我们通过在我们自定义的ErrorDecoder实现中提取原始消息来检索它:
public class RetreiveMessageErrorDecoder implements ErrorDecoder {
private ErrorDecoder errorDecoder = new Default();
@Override
public Exception decode(String methodKey, Response response) {
ExceptionMessage message = null;
try (InputStream bodyIs = response.body()
.asInputStream()) {
ObjectMapper mapper = new ObjectMapper();
message = mapper.readValue(bodyIs, ExceptionMessage.class);
} catch (IOException e) {
return new Exception(e.getMessage());
}
switch (response.status()) {
case 400:
return new BadRequestException(message.getMessage() != null ? message.getMessage() : "Bad Request");
case 404:
return new NotFoundException(message.getMessage() != null ? message.getMessage() : "Not found");
default:
return errorDecoder.decode(methodKey, response);
}
}
}
在我们的实现中,我们添加了基于可能错误的逻辑,因此我们可以自定义它们以满足我们的要求。在我们的 switch 块的默认情况下,我们使用ErrorDecoder的默认 实现。
当状态不在 2xx 范围内时,默认实现会解码 HTTP 响应。当throwable是retryable 时,它应该是RetryableException 的子类型,并且我们应该尽可能引发特定于应用程序的异常。
要配置我们自定义的ErrorDecoder,我们将在 Feign 配置中添加我们的实现作为 bean:
@Bean
public ErrorDecoder errorDecoder() {
return new RetreiveMessageErrorDecoder();
}
现在,让我们看看原始消息的异常:
com.blogdemo.cloud.openfeign.exception.NotFoundException: Page Not found
at com.blogdemo.cloud.openfeign.fileupload.config.RetreiveMessageErrorDecoder.decode(RetreiveMessageErrorDecoder.java:30) ~[classes/:na]
at feign.AsyncResponseHandler.handleResponse(AsyncResponseHandler.java:96) ~[feign-core-11.7.jar:na]