@ResponseStatus用于声明式指定HTTP状态码,适用于状态码固定场景:可标注在控制器方法(如201创建成功)或自定义异常类上,配合@ExceptionHandler统一处理响应体;不支持动态状态码,此时应使用ResponseEntity。

在 Java 的 Spring REST 接口中,@ResponseStatus 可用于直接为控制器方法或异常类指定 HTTP 状态码,无需手动设置 ResponseEntity 或操作 HttpServletResponse。它简洁、声明式,适合业务逻辑明确、状态码固定的场景。
在 Controller 方法上直接标注状态码
适用于成功响应中需返回非 200 的标准状态码(如创建成功用 201、无内容用 204):
- 方法返回值可以是 void、对象或
ResponseEntity(但若用了@ResponseStatus,再返回ResponseEntity会以后者为准,前者被忽略) - 状态码必须是
HttpStatus枚举中的合法值,推荐使用枚举而非数字,提升可读性与类型安全
示例:
@PostMapping("/users")
@ResponseStatus(HttpStatus.CREATED)
public User createUser(@RequestBody User user) {
return userService.save(user);
}配合自定义业务异常统一返回错误码
更常见也更推荐的做法:将 @ResponseStatus 标在自定义异常类上,再在控制器中抛出该异常。Spring 会自动将其映射为对应状态码的响应,并可结合 @ExceptionHandler 增强响应体(如添加错误信息):
- 异常类本身不处理响应体,只负责“声明状态码”
- 实际响应内容(JSON 错误结构)由全局异常处理器(
@ControllerAdvice+@ExceptionHandler)统一组织
示例:
@ResponseStatus(HttpStatus.BAD_REQUEST)
public class InvalidUserException extends RuntimeException {
public InvalidUserException(String message) {
super(message);
}
}
@RestController
public class UserController {
@PostMapping("/users")
public User createUser(@RequestBody User user) {
if (user.getEmail() == null) {
throw new InvalidUserException("Email is required");
}
return userService.save(user);
}
}注意与 @ExceptionHandler 的协作关系
@ResponseStatus 和 @ExceptionHandler 可共存,但作用不同:
-
@ResponseStatus在异常类上:告诉 Spring “这个异常默认应返回什么 HTTP 状态码” -
@ExceptionHandler在处理器方法中:决定“这个异常具体返回什么响应体(如 JSON 字段、日志、兜底逻辑)” - 若两者都存在,状态码以异常类上的
@ResponseStatus为准;响应体以@ExceptionHandler返回的内容为准
典型组合:
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(InvalidUserException.class)
public ResponseEntity<errorresponse> handleInvalidUser(InvalidUserException e) {
ErrorResponse error = new ErrorResponse("VALIDATION_FAILED", e.getMessage());
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(error);
}
}</errorresponse>不适用的场景要避免
@ResponseStatus 是静态声明,无法动态计算状态码(比如根据参数值返回 404 或 409)。此时必须改用 ResponseEntity:
- 需要根据运行时条件选择不同状态码
- 需要同时设置状态码、响应头和响应体(如带 Location 头的 201 响应)
- 需要覆盖默认状态码(例如某个异常通常 500,但某次调用想返回 409)
替代写法示例:
@GetMapping("/users/{id}")
public ResponseEntity<user> getUser(@PathVariable Long id) {
User user = userService.findById(id);
if (user == null) {
return ResponseEntity.notFound().build();
}
return ResponseEntity.ok(user);
}</user>Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











