1. 概述
一個 RESTful 服務可能因為各種原因而失敗。 在本教程中,我們將探討如何從 Feign 客户端檢索原始消息,如果集成的 REST 服務拋出錯誤。
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 塊的默認情況下,我們正在使用 Default 的 ErrorDecoder 的實現。
Default 實現在 HTTP 響應狀態碼不在 2xx 範圍內時解碼 HTTP 響應。當 throwable 是 retryable 時,它應該是 RetryableException 的子類型,並且我們應該在可能的情況下引發應用程序特定的異常。
要配置我們自定義的 ErrorDecoder,我們將把我們的實現作為 Bean 添加到 Feign 配置中:
@Bean
public ErrorDecoder errorDecoder() {
return new RetreiveMessageErrorDecoder();
}
現在,讓我們看看帶有原始消息的異常:
com.baeldung.cloud.openfeign.exception.NotFoundException: Page Not found
at com.baeldung.cloud.openfeign.fileupload.config.RetreiveMessageErrorDecoder.decode(RetreiveMessageErrorDecoder.java:30) ~[classes/:na]
at feign.AsyncResponseHandler.handleResponse(AsyncResponseHandler.java:96) ~[feign-core-11.7.jar:na]
4. 結論
在本文中,我們演示瞭如何自定義 ErrorDecoder,以便捕獲 Feign 錯誤以獲取原始消息。