@responsestatus是spring mvc中声明式映射业务异常为http状态码的轻量方式,直接标注在继承runtimeexception的自定义异常类上,由responsestatusexceptionresolver解析生效,未被@exceptionhandler拦截时自动设置响应码。

Spring MVC 中,@ResponseStatus 是一种轻量、声明式的方式,让自定义业务异常自动映射为指定的 HTTP 状态码,无需额外配置异常处理器(如 @ControllerAdvice),特别适合语义明确、状态码固定的业务异常场景。
直接在自定义异常类上标注 @ResponseStatus
这是最常用也最推荐的方式。只要异常类本身被 Spring 捕获(比如在 Controller 层抛出),且未被其他异常处理器提前拦截,Spring 就会根据该注解设置响应状态码。
- 异常类需继承
RuntimeException(运行时异常)或Exception(检查型异常),但建议用运行时异常,避免强制 try-catch -
@ResponseStatus必须指定value(即HttpStatus枚举),可选填reason(作为响应 reason phrase,非必需) - 该注解只对“未被捕获”的异常生效;若你在 Controller 内 catch 并手动返回 ResponseEntity,则注解无效
示例:
@ResponseStatus(value = HttpStatus.NOT_FOUND, reason = "用户不存在")
public class UserNotFoundException extends RuntimeException {
public UserNotFoundException(String userId) {
super("User not found: " + userId);
}
}
Controller 中直接抛出即可:
@GetMapping("/users/{id}")
public User getUser(@PathVariable String id) {
User user = userService.findById(id);
if (user == null) {
throw new UserNotFoundException(id); // 响应状态码自动变为 404
}
return user;
}
配合 @ExceptionHandler 使用更灵活的控制
当需要统一处理多种异常、补充响应体(如错误详情 JSON)、记录日志,或对同一异常做不同状态码判定(如根据上下文返回 401 或 403),就应在 @ControllerAdvice 或控制器内用 @ExceptionHandler 显式处理。
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
- 此时
@ResponseStatus在异常类上的声明会被忽略 —— Spring 优先执行@ExceptionHandler方法 - 你可以在 handler 方法中主动设置状态码:
ResponseEntity.status(HttpStatus.BAD_REQUEST).body(...),或使用@ResponseStatus标注 handler 方法本身 - 推荐方式:handler 方法返回
ResponseEntity,既可控状态码,又可定制 body 和 headers
示例:
@ResponseStatus(HttpStatus.CONFLICT)
@ExceptionHandler(DuplicateResourceException.class)
public ResponseEntity<errorresponse> handleDuplicateResource(DuplicateResourceException e) {
ErrorResponse error = new ErrorResponse("资源已存在", e.getMessage());
return ResponseEntity.status(HttpStatus.CONFLICT).body(error);
}</errorresponse>
注意作用域与生效条件
@ResponseStatus 不是万能的,它的生效依赖 Spring MVC 的异常解析机制,有几条关键约束:
- 仅对由 DispatcherServlet 抛出、且未被任何
@ExceptionHandler或HandlerExceptionResolver拦截的异常起作用 - 若全局异常处理器(如
@ControllerAdvice)捕获了该异常,即使没写逻辑也会“吞掉”注解效果 - Spring Boot 默认注册了
ResponseStatusExceptionResolver,它专门负责识别@ResponseStatus注解,所以 Boot 项目默认支持 - 不能用于异步方法(
@Async)或 WebFlux(需用ResponseStatusException或ServerWebExchange手动设状态)
替代方案:ResponseStatusException(更轻量、无需定义类)
如果只是偶尔抛出带状态码的异常,不想为每种业务错误都建一个类,可以直接用 Spring 内置的 ResponseStatusException:
- 它是
RuntimeException子类,构造时传入HttpStatus和可选 message - 同样被
ResponseStatusExceptionResolver处理,效果等同于自定义带@ResponseStatus的异常 - 适合原型开发或简单场景,但不利于统一错误分类和日志追踪
示例:
@GetMapping("/orders/{id}")
public Order getOrder(@PathVariable Long id) {
Order order = orderService.findById(id);
if (order == null) {
throw new ResponseStatusException(HttpStatus.NOT_FOUND, "订单未找到");
}
return order;
}Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










