Error Responses
REST 服务的一个常见要求是在错误响应的主体中包含详细信息。Spring 框架支持“用于 HTTP API 的问题详情”规范,https://datatracker.ietf.org/doc/html/rfc9457[RFC 9457]。 以下是此支持的主要抽象:
-
ProblemDetail
— RFC 9457 问题详情的表示;一个简单容器,既用于规范中定义的标准字段,也用于非标准字段。 -
ErrorResponse
— 用于公开 HTTP 错误响应详情(包括 HTTP 状态、响应头和 RFC 9457 格式的正文)的契约;允许异常封装并公开它们如何映射到 HTTP 响应的详情。所有 Spring MVC 异常都实现此功能。 -
ErrorResponseException
— 其他 `ErrorResponse`实现可用作方便的基本类。 -
ResponseEntityExceptionHandler
— 方便的基本类,用于 @ControllerAdvice处理所有 Spring MVC 异常和任何ErrorResponseException
,并呈现带正文的错误响应。
Render
可以从任何 @ExceptionHandler
或 @RequestMapping
方法返回 ProblemDetail
或 ErrorResponse
来呈现 RFC 9457 响应。该处理过程如下:
-
`ProblemDetail`的 `status`属性确定 HTTP 状态。
-
`ProblemDetail`的 `instance`属性来自当前 URL 路径设置(如果尚未设置)。
-
为了进行内容协商,在呈现 `ProblemDetail`时,Jackson `HttpMessageConverter`优先使用“application/problem+json”而不是“application/json”,还将在找不到兼容媒体类型时使用后者。
要为 Spring WebFlux 异常和任何 ErrorResponseException
启用 RFC 9457 响应,请扩展 ResponseEntityExceptionHandler
并将其声明为 Spring 配置中的 @ControllerAdvice。该处理程序有一个 @ExceptionHandler
方法,该方法处理任何 ErrorResponse
异常,其中包括所有内置网络异常。您可以添加更多异常处理方法,并使用受保护方法将任何异常映射到 ProblemDetail
。
您可以通过 MVC Config 使用 WebMvcConfigurer
注册 ErrorResponse
拦截器。使用它来拦截任何 RFC 7807 响应并采取一些操作。
Non-Standard Fields
可以通过两种方法扩展超出 RFC 9457 响应的非标准字段。
方法一,插入到 ProblemDetail
的“属性”Map
中。在使用 Jackson 库时,Spring Framework 会注册 ProblemDetailJacksonMixin
,以确保此“属性”Map
被解包并呈现为响应中的顶级 JSON 属性,同样,在反序列化期间的任何未知属性也被插入到此 Map
中。
你也可以扩展 ProblemDetail
以添加非标准的专用属性。ProblemDetail
中的拷贝构造函数允许子类轻松从现有的 ProblemDetail
创建。它可以集中管理,比如在 @ControllerAdvice
中,比如 ResponseEntityExceptionHandler
从一个 ProblemDetail
的异常重新创建一个子类,子类具有附加的非标准的字段。
Customization and i18n
一种常见的需求是自定义和国际化错误的响应详情。对于 Spring MVC 的异常自定义问题详情也是一种良好的实践,可以避免泄露实现详情。本部分介绍对其的支持。
ErrorResponse
公开消息代码以用于“类型”、“标题”和“详情”,以及用于“详情”字段的消息代码参数。ResponseEntityExceptionHandler
通过 MessageSource 确定这些,并相应地更新对应的 ProblemDetail
字段。
消息代码的默认策略如下:
-
"type":
problemDetail.type.[fully qualified exception class name]
-
"title":
problemDetail.title.[fully qualified exception class name]
-
"detail":
problemDetail.[fully qualified exception class name][suffix]
一个 ErrorResponse
可能会公开不止一个消息代码,通常会在默认的消息代码后添加后缀。下表列出了消息代码和 Spring MVC 异常参数:
Exception | Message Code | Message Code Arguments |
---|---|---|
|
(default) |
|
|
(default) |
|
|
(default) |
|
|
(default) |
|
|
(default) + ".parseError" |
|
|
(default) |
|
|
(default) + ".parseError" |
|
|
(default) |
|
|
(default) |
|
|
(default) |
|
|
(default) |
|
|
(default) |
|
|
(default) |
|
|
(default) |
|
|
(default) |
|
|
(default) |
|
|
(default) |
|
|
(default) |
|
|
(default) |
|
|
(default) |
|
|
(default) |
|
与其他异常不同, |