Skip to content

Spring 中的 @ResponseStatus 注解的作用是什么? ​

  • 标签:后端、Spring

🏛 业务架构师 ​

@ResponseStatus 的作用是为响应指定 HTTP 状态码,两种用法:

  1. 标在 @ExceptionHandler 方法或 Controller 方法上:该响应返回指定状态码,如 @ResponseStatus(HttpStatus.NOT_FOUND);
  2. 标在自定义异常类上:这个异常被抛出到顶层时,响应自动带上对应状态码——轻量场景不用写 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 各有含义,客户端、网关、监控、重试策略都依赖状态码做行为决策。

我的实践判断:

  1. 业务错误不建议全部硬套 HTTP 码——状态码表达传输与协议层语义,业务码放 body;混用会出现「一个 404 到底是资源不存在还是参数错误」的契约争议;
  2. 它适合异常即 HTTP 语义的场景:资源不存在 404、幂等冲突 409、限流 429、未认证 401;
  3. 监控按状态码聚合(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 返回为准,注解被覆盖——状态码来源要可预期

一句话:小工具注解,配合统一返回体 + 全局异常处理器才干净,单独滥用会把错误处理逻辑打散在各处。