错误响应
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
方法返回 ProblemDetail
或 ErrorResponse
来渲染 RFC 9457 响应。这将按以下步骤处理:
-
ProblemDetail
的status
属性决定 HTTP 状态。 -
如果
ProblemDetail
的instance
属性尚未设置,则会从当前 URL 路径设置它。 -
对于内容协商,Jackson
HttpMessageConverter
在渲染ProblemDetail
时优先使用 "application/problem+json" 而不是 "application/json",如果未找到兼容的媒体类型,它也会回退到 "application/problem+json"。
要为 Spring WebFlux 异常和任何 ErrorResponseException
启用 RFC 9457 响应,请扩展 ResponseEntityExceptionHandler
并将其声明为 Spring 配置中的 @ControllerAdvice。处理程序有一个 @ExceptionHandler
方法,用于处理任何 ErrorResponse
异常,包括所有内置的 Web 异常。您可以添加更多异常处理方法,并使用受保护的方法将任何异常映射到 ProblemDetail
。
非标准字段
您可以通过两种方式之一扩展 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 异常的消息代码和参数。
异常 | 消息代码 | 消息代码参数 |
---|---|---|
|
(默认) |
|
|
(默认) |
|
|
(默认) |
|
|
(默认) |
|
|
(默认) + ".parseError" |
|
|
(默认) |
|
|
(默认) |
|
|
(默认) + ".parseError" |
|
|
(默认) |
|
|
(默认) |
|
与其他异常不同,WebExchangeBindException 和 HandlerMethodValidationException 的消息参数基于 MessageSourceResolvable 错误列表,这些错误也可以通过 MessageSource 资源包进行自定义。有关详细信息,请参阅 自定义验证错误。
|