錯誤響應

REST 服務的一個常見需求是在錯誤響應的正文中包含詳細資訊。Spring 框架支援 "HTTP API 的問題詳情" 規範 RFC 9457

以下是此支援的主要抽象

  • ProblemDetail — RFC 9457 問題詳情的表示;一個簡單的容器,用於規範中定義的標準欄位和非標準欄位。

  • ErrorResponse — 暴露 HTTP 錯誤響應詳情的契約,包括 HTTP 狀態、響應頭和 RFC 9457 格式的正文;這允許異常封裝和暴露它們如何對映到 HTTP 響應的詳情。所有 Spring WebFlux 異常都實現了這一點。

  • ErrorResponseException — 其他類可以將其用作便捷基類的基本 ErrorResponse 實現。

  • ResponseEntityExceptionHandler — 用於 @ControllerAdvice 的便捷基類,用於處理所有 Spring WebFlux 異常和任何 ErrorResponseException,並渲染帶正文的錯誤響應。

渲染

您可以從任何 @ExceptionHandler 或任何 @RequestMapping 方法返回 ProblemDetailErrorResponse 以渲染 RFC 9457 響應。處理過程如下

  • ProblemDetailstatus 屬性決定 HTTP 狀態。

  • 如果尚未設定,ProblemDetailinstance 屬性將從當前 URL 路徑中設定。

  • 對於內容協商,當渲染 ProblemDetail 時,Jackson HttpMessageConverter 優先選擇 "application/problem+json" 而不是 "application/json",並且在未找到相容媒體型別時也會回退到它。

要為 Spring WebFlux 異常和任何 ErrorResponseException 啟用 RFC 9457 響應,請擴充套件 ResponseEntityExceptionHandler 並將其宣告為 Spring 配置中的 @ControllerAdvice。該處理程式有一個 @ExceptionHandler 方法,用於處理任何 ErrorResponse 異常,其中包含所有內建的 Web 異常。您可以新增更多異常處理方法,並使用受保護的方法將任何異常對映到 ProblemDetail

您可以透過 WebFlux 配置WebFluxConfigurer 註冊 ErrorResponse 攔截器。使用它來攔截任何 RFC 9457 響應並執行某些操作。

非標準欄位

您可以透過以下兩種方式之一擴充套件帶有非標準欄位的 RFC 9457 響應。

其一,插入到 ProblemDetail 的 "properties" Map 中。使用 Jackson 庫時,Spring 框架會註冊 ProblemDetailJacksonMixin,確保此 "properties" Map 被解包並渲染為響應中的頂級 JSON 屬性,並且在反序列化期間任何未知屬性也會插入到此 Map 中。

您還可以擴充套件 ProblemDetail 以新增專用的非標準屬性。ProblemDetail 中的複製建構函式允許子類輕鬆地從現有 ProblemDetail 建立。這可以集中完成,例如,從 @ControllerAdvice(如 ResponseEntityExceptionHandler)中重新建立異常的 ProblemDetail 到帶有附加非標準欄位的子類。

自定義和國際化

自定義和國際化錯誤響應詳情是一個常見需求。自定義 Spring WebFlux 異常的問題詳情以避免暴露實現細節也是一個好習慣。本節描述了對此的支援。

ErrorResponse 暴露了 "type"、"title" 和 "detail" 的訊息程式碼,以及 "detail" 欄位的訊息程式碼引數。ResponseEntityExceptionHandler 透過 MessageSource 解析這些程式碼,並相應地更新相應的 ProblemDetail 欄位。

訊息程式碼的預設策略遵循以下模式

problemDetail.[type|title|detail].[完全限定的異常類名]

ErrorResponse 可能會暴露多個訊息程式碼,通常會在預設訊息程式碼後新增一個字尾。下表列出了 Spring WebFlux 異常的訊息程式碼和引數

異常 訊息程式碼 訊息程式碼引數

HandlerMethodValidationException

(預設)

{0} 列出所有驗證錯誤。每個錯誤的訊息程式碼和引數也透過 MessageSource 解析。

MethodNotAllowedException

(預設)

{0} 當前的 HTTP 方法,{1} 支援的 HTTP 方法列表

MissingRequestValueException

(預設)

{0} 值的標籤(例如,"請求頭"、"cookie 值" 等),{1} 值名稱

NotAcceptableStatusException

(預設)

{0} 支援的媒體型別列表

NotAcceptableStatusException

(預設)+ ".parseError"

ServerErrorException

(預設)

{0} 提供給類建構函式的失敗原因

UnsupportedMediaTypeStatusException

(預設)

{0} 不支援的媒體型別,{1} 支援的媒體型別列表

UnsupportedMediaTypeStatusException

(預設)+ ".parseError"

UnsatisfiedRequestParameterException

(預設)

{0} 引數條件列表

WebExchangeBindException

(預設)

{0} 全域性錯誤列表,{1} 欄位錯誤列表。每個錯誤的訊息程式碼和引數也透過 MessageSource 解析。

與其他異常不同,WebExchangeBindExceptionHandlerMethodValidationException 的訊息引數基於 MessageSourceResolvable 錯誤列表,這些錯誤也可以透過 MessageSource 資源包進行自定義。有關更多詳細資訊,請參見 自定義驗證錯誤

客戶端處理

客戶端應用程式在使用 WebClient 時可以捕獲 WebClientResponseException,或者在使用 RestTemplate 時捕獲 RestClientResponseException,並使用它們的 getResponseBodyAs 方法將錯誤響應正文解碼為任何目標型別,例如 ProblemDetailProblemDetail 的子類。

© . This site is unofficial and not affiliated with VMware.