FeignErrorDecoderから元のメッセージを取得する
1. 概要
RESTfulサービスは、さまざまな理由で失敗する可能性があります。 このチュートリアルでは、統合されたRESTサービスがエラーをスローした場合に、Feignクライアントから元のメッセージを取得する方法を見ていきます。
2. 偽のクライアント
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 Javabeanを作成します。
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);
}
}
}
この実装では、発生する可能性のあるエラーに基づいてロジックを追加したため、要件に合わせてそれらをカスタマイズできます。 スイッチブロックのデフォルトの場合、を使用していますデフォルトの実装
Default 実装は、ステータスが2xxの範囲にない場合にHTTP応答をデコードします。 throwableがretryableの場合、 RetryableException、のサブタイプである必要があり、可能な場合は常にアプリケーション固有の例外を発生させる必要があります。
カスタマイズされたErrorDecoderを構成するために、Feign構成にbeanとして実装を追加します。
@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エラーをキャッチして元のメッセージをフェッチできるようにする方法を示しました。
いつものように、このチュートリアルで使用されるすべてのコードサンプルは、GitHubでから入手できます。