最新の安定バージョンについては、Spring Framework 6.2.3 を使用してください! |
エラーレスポンス
REST サービスの一般的な要件は、エラーレスポンスの本文に詳細を含めることです。Spring Framework は、「HTTP API の問題の詳細」仕様 RFC 7807 (英語) をサポートします。
このサポートの主な抽象化は次のとおりです。
ProblemDetail
— RFC 7807 問題の詳細の表現。仕様で定義された標準フィールドと非標準フィールドの両方の単純なコンテナー。ErrorResponse
— HTTP ステータス、レスポンスヘッダー、RFC 7807 の形式の本文など、HTTP エラーレスポンスの詳細を公開する契約。これにより、例外をカプセル化し、HTTP レスポンスへのマッピング方法の詳細を公開できます。すべての Spring MVC 例外がこれを実装しています。ErrorResponseException
— 他の人が便利な基本クラスとして使用できる基本的なErrorResponse
実装。ResponseEntityExceptionHandler
— すべての Spring MVC 例外と任意のErrorResponseException
を処理し、本文でエラーレスポンスをレンダリングする @ControllerAdvice の便利な基本クラス。
レンダリング
RFC 7807 レスポンスをレンダリングするために、任意の @ExceptionHandler
または任意の @RequestMapping
メソッドから ProblemDetail
または ErrorResponse
を返すことができます。これは次のように処理されます。
ProblemDetail
のstatus
プロパティは、HTTP ステータスを決定します。ProblemDetail
のinstance
プロパティは、まだ設定されていない場合、現在の URL パスから設定されます。コンテンツネゴシエーションの場合、Jackson
HttpMessageConverter
はProblemDetail
をレンダリングするときに "application/json" よりも "application/problem+json" を優先し、互換性のあるメディア型が見つからない場合はそれにフォールバックします。
Spring WebFlux 例外および任意の ErrorResponseException
に対して RFC 7807 レスポンスを有効にするには、ResponseEntityExceptionHandler
を継承し、Spring 構成で @ControllerAdvice として宣言します。ハンドラーには、すべての組み込み Web 例外を含む ErrorResponse
例外を処理する @ExceptionHandler
メソッドがあります。例外処理メソッドをさらに追加し、protected メソッドを使用して例外を ProblemDetail
にマップできます。
非標準フィールド
2 つの方法のいずれかで、非標準フィールドを使用して RFC 7807 レスポンスを継承できます。
1 つは、ProblemDetail
の「プロパティ」 Map
に挿入します。Jackson ライブラリを使用する場合、Spring Framework は ProblemDetailJacksonMixin
を登録します。これにより、この「プロパティ」 Map
がラップ解除され、レスポンスで最上位の JSON プロパティとしてレンダリングされます。同様に、逆直列化中に不明なプロパティがこの Map
に挿入されます。
また、ProblemDetail
を継承して、専用の非標準プロパティを追加することもできます。ProblemDetail
のコピーコンストラクターを使うと、既存の ProblemDetail
からサブクラスを簡単に作成することができます。これは、たとえば、例外の ProblemDetail
を再作成する ResponseEntityExceptionHandler
などの @ControllerAdvice
から、非標準のフィールドを追加したサブクラスを一元的に作成することが可能です。
国際化対応
エラーレスポンスの詳細を国際化することは一般的な要件であり、Spring MVC 例外の問題の詳細をカスタマイズすることをお勧めします。これは次のようにサポートされています。
各
ErrorResponse
は、MessageSource を介して「詳細」フィールドを解決するためのメッセージコードと引数を公開します。実際のメッセージコード値は、プレースホルダーでパラメーター化されます。引数から展開される"HTTP method {0} not supported"
。各
ErrorResponse
は、「タイトル」フィールドを解決するためのメッセージコードも公開します。ResponseEntityExceptionHandler
は、メッセージコードと引数を使用して、「詳細」フィールドと「タイトル」フィールドを解決します。
デフォルトでは、「詳細」フィールドのメッセージコードは "problemDetail" + 完全修飾例外クラス名です。例外によっては追加のメッセージコードが公開される場合があり、その場合はデフォルトのメッセージコードにサフィックスが追加されます。次の表に、Spring MVC 例外のメッセージ引数とコードを示します。
例外 | メッセージコード | メッセージコードの引数 |
---|---|---|
| (デフォルト) | |
| (デフォルト) |
|
| (デフォルト) |
|
| (デフォルト) + ".parseError" | |
| (デフォルト) |
|
| (デフォルト) + ".parseError" | |
| (デフォルト) | |
| (デフォルト) | |
| (デフォルト) |
|
| (デフォルト) |
|
| (デフォルト) |
|
| (デフォルト) |
|
| (デフォルト) |
|
| (デフォルト) |
|
| (デフォルト) |
|
| (デフォルト) |
|
| (デフォルト) | |
| (デフォルト) |
|
| (デフォルト) |
|
デフォルトでは、"title" フィールドのメッセージコードは "problemDetail.title" + 完全修飾例外クラス名です。
クライアントハンドリング
クライアントアプリケーションは、WebClient
を使用する場合は WebClientResponseException
をキャッチし、RestTemplate
を使用する場合は RestClientResponseException
をキャッチし、それらの getResponseBodyAs
メソッドを使用して、エラーレスポンスの本文を ProblemDetail
や ProblemDetail
のサブクラスなどの任意のターゲット型にデコードします。