错误响应 (Error Responses)
对于 REST 服务来说,在错误响应体中包含详细的错误信息是一个常见的需求。Spring Framework 支持针对 HTTP API 的问题细节规范(RFC 9457)。
核心组件
1. ProblemDetail
ProblemDetail 是 RFC 9457 的核心容器。它包含了标准字段(如 type, title, status, detail, instance)以及自定义字段。
2. ErrorResponse
这是一个契约接口,允许异常类自行封装它们该如何映射到 HTTP 响应。所有的 Spring MVC 内置异常都实现了这个接口。
3. ResponseEntityExceptionHandler
这是 @ControllerAdvice 的一个非常便捷的基类。通过继承它,你可以自动地让所有标准 Spring MVC 异常都按 RFC 9457 格式渲染。
渲染机制
当你返回 ProblemDetail 或 ErrorResponse 时:
- Jackson 转换器会优先使用
application/problem+json媒体类型。 instance字段会自动设置为当前的 URL 路径。
补充教学
1. 为什么推荐 RFC 9457?
在过去,每个公司甚至每个项目组定义的错误格式都不一样(有的叫 code/msg,有的叫 errorCode/errorInfo)。 RFC 9457 提供了一个国际标准。这意味着通用的 HTTP 客户端(如库或调试工具)能够一致地理解和展示你的 API 错误。
2. 国际化 (i18n)
ErrorResponse 暴露了用于“标题”和“详情”的消息代码。你可以通过 MessageSource 为不同的语言配置不同的错误提示。
properties
# messages.properties
problemDetail.title.org.springframework.web.bind.MissingServletRequestParameterException=缺少必要参数3. 性能建议
虽然 ProblemDetail 很强大,但它主要用于 REST 接口。对于传统的面向页面的 Web 项目,通常还是推荐使用 ExceptionHandler 跳转到通用的 error 页面,而不是返回 JSON。