错误响应

REST服务的常见要求是在错误响应的主体中包含详细信息。Spring Framework支持“HTTP API问题详细信息”规范,RFC 7807

以下是此支持的主要抽象:

  • ProblemDetail — RFC 7807问题详细信息的表示;一个简单的容器,用于存储规范中定义的标准字段和非标准字段。

  • ErrorResponse — 用于公开HTTP错误响应详细信息的契约,包括HTTP状态、响应头和RFC 7807格式的主体;这允许异常封装和公开它们映射到HTTP响应的详细信息。所有Spring MVC异常都实现了这一点。

  • ErrorResponseException — 其他人可以使用的基本ErrorResponse实现,作为方便的基类。

  • ResponseEntityExceptionHandler — 用于处理所有Spring MVC异常和任何ErrorResponseException@ControllerAdvice的方便基类,并呈现带有主体的错误响应。

渲染

@ExceptionHandler或任何 @RequestMapping方法返回 ProblemDetailErrorResponse,以呈现RFC 7807响应。处理如下:

  • ProblemDetailstatus属性确定HTTP状态。

  • ProblemDetailinstance属性从当前URL路径设置,如果尚未设置。

  • ProblemDetail时,Jackson HttpMessageConverter优先选择“application/problem+json”而不是“application/json”,如果找不到兼容的媒体类型,还会回退到它。

ErrorResponseException启用RFC 7807响应,请扩展 ResponseEntityExceptionHandler并在Spring配置中声明为 @ControllerAdvice。处理程序具有一个 @ExceptionHandler方法,用于处理任何 ErrorResponse异常,其中包括所有内置的Web异常。您可以添加更多异常处理方法,并使用受保护的方法将任何异常映射到 ProblemDetail

非标准字段

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字段。

消息代码的默认策略遵循以下模式:

problemDetail.[type|title|detail].[完全限定的异常类名]

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的子类。