Spring 中的 @ResponseStatus 注解的作用是什么?
- 标签:后端、Spring
🏛 业务架构师
@ResponseStatus 的作用是为响应指定 HTTP 状态码,两种用法:
- 标在
@ExceptionHandler方法或 Controller 方法上:该响应返回指定状态码,如@ResponseStatus(HttpStatus.NOT_FOUND); - 标在自定义异常类上:这个异常被抛出到顶层时,响应自动带上对应状态码——轻量场景不用写 handler 也能返回规范状态。
架构师视角,这个注解背后是HTTP 语义在 API 治理中的正确性问题。我的团队规范把状态码映射成业务契约:
- 2xx:成功(200 查询 / 201 创建);
- 400:参数错误;401/403:认证授权失败;404:资源不存在;409:业务冲突(重复下单);
- 5xx:系统故障。
为什么较真状态码:网关、监控、重试策略全依赖它——负载均衡和调用方的重试逻辑通常"遇 5xx 才重试",你把业务失败也返回 500,会触发无意义的重试放大流量;你把系统故障返回 200 包在 JSON 错误码里,网关的成功率监控就失明,故障发现机制直接失效。
2026 视角的补充:前后端分离 + 内部 RPC 化(Feign/OpenFeign 的 errorDecoder)场景下,状态码语义的一致性决定全链路熔断与重试行为是否正确。状态码不是细节,是可观测性和容错体系的信号协议。
🏗 系统架构师
作用:把方法或异常类映射为指定 HTTP 状态码与原因(如 NOT_FOUND、CONFLICT)。标在异常类上抛出即生效,标在 Handler 方法上响应即携带该状态码。
架构定位:它是「API 语义化状态码」的工具——REST 契约不只在 body,状态码本身就是接口语义:200/201/204/400/401/403/404/409/429 各有含义,客户端、网关、监控、重试策略都依赖状态码做行为决策。
我的实践判断:
- 业务错误不建议全部硬套 HTTP 码——状态码表达传输与协议层语义,业务码放 body;混用会出现「一个 404 到底是资源不存在还是参数错误」的契约争议;
- 它适合异常即 HTTP 语义的场景:资源不存在 404、幂等冲突 409、限流 429、未认证 401;
- 监控按状态码聚合(5xx 率即可用性 SLO),错误码规划直接决定可观测性质量。
💻 全栈开发专家
两个用法:
1. 标在 handler 方法上:指定响应状态码:
java
@PostMapping("/orders")
@ResponseStatus(HttpStatus.CREATED) // 201 而不是默认 200
public OrderVO create(@RequestBody OrderReq req) { ... }2. 标在异常类上:抛出即返回对应状态码:
java
@ResponseStatus(HttpStatus.NOT_FOUND)
public class OrderNotFoundException extends RuntimeException { }RESTful 规范里是老朋友:创建 201、删除 204、找不到 404,前端按状态码分流。
坑要讲两条:
- 标在异常类上时响应体由异常 message 决定,和
@RestControllerAdvice混用容易出现"有的 404 有 body 有的没有",团队要约定单一风格 - 它只影响状态码,不改序列化行为;被
@ExceptionHandler接住的异常以 handler 返回为准,注解被覆盖——状态码来源要可预期
一句话:小工具注解,配合统一返回体 + 全局异常处理器才干净,单独滥用会把错误处理逻辑打散在各处。