錯誤響應

REST 服務的一個常見要求是在錯誤響應體中包含詳細資訊。Spring Framework 支援“HTTP API 的問題詳情”規範,RFC 9457

以下是此支援的主要抽象

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

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

  • ErrorResponseException — 其他類可以作為方便的基類的基本 ErrorResponse 實現。

  • ResponseEntityExceptionHandler — 一個方便的基類,用於處理所有 Spring MVC 異常和任何 ErrorResponseException,並渲染帶響應體的錯誤響應的 @ControllerAdvice

渲染

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

  • ProblemDetailstatus 屬性決定 HTTP 狀態。

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

  • 對於內容協商,當渲染 ProblemDetail 時,Jackson HttpMessageConverter 優先使用“application/problem+json”而不是“application/json”,如果沒有找到相容的媒體型別,也會回退到它。

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

您可以透過使用 WebMvcConfigurerMVC 配置來註冊 ErrorResponse 攔截器。使用它來攔截任何 RFC 9457 響應並採取一些行動。

非標準欄位

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

其一,插入到 ProblemDetail 的“properties” Map 中。當使用 Jackson 庫時,Spring Framework 註冊 ProblemDetailJacksonMixin,它確保此“properties” Map 被解包並渲染為響應中的頂級 JSON 屬性,同樣,反序列化期間的任何未知屬性都會插入到此 Map 中。

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

定製和國際化

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

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

訊息程式碼的預設策略如下

  • "type": problemDetail.type.[完全限定的異常類名]

  • "title": problemDetail.title.[完全限定的異常類名]

  • "detail": problemDetail.[完全限定的異常類名][字尾]

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

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

AsyncRequestTimeoutException

(預設)

ConversionNotSupportedException

(預設)

{0} 屬性名,{1} 屬性值

HandlerMethodValidationException

(預設)

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

HttpMediaTypeNotAcceptableException

(預設)

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

HttpMediaTypeNotAcceptableException

(預設) + ".parseError"

HttpMediaTypeNotSupportedException

(預設)

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

HttpMediaTypeNotSupportedException

(預設) + ".parseError"

HttpMessageNotReadableException

(預設)

HttpMessageNotWritableException

(預設)

HttpRequestMethodNotSupportedException

(預設)

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

MethodArgumentNotValidException

(預設)

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

MissingRequestHeaderException

(預設)

{0} 請求頭名稱

MissingServletRequestParameterException

(預設)

{0} 請求引數名稱

MissingMatrixVariableException

(預設)

{0} 矩陣變數名稱

MissingPathVariableException

(預設)

{0} 路徑變數名稱

MissingRequestCookieException

(預設)

{0} Cookie 名稱

MissingServletRequestPartException

(預設)

{0} 部分名稱

NoHandlerFoundException

(預設)

NoResourceFoundException

(預設)

TypeMismatchException

(預設)

{0} 屬性名,{1} 屬性值

UnsatisfiedServletRequestParameterException

(預設)

{0} 引數條件列表

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

客戶端處理

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

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