错误响应

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.