@ResponseStatus 注解详解
@ResponseStatus 注解详解
📋 概述
@ResponseStatus
是 Spring 框架提供的一个核心注解,用于在处理 HTTP 请求时设置响应的状态码和原因短语。它可以应用于控制器方法或异常类上,让开发者能够更精确地控制 API 的响应状态。
🎯 主要特性
- ✅ 支持在方法上直接设置响应状态码
- ✅ 支持在异常类上定义默认状态码
- ✅ 提供原因短语的自定义设置
- ✅ 与全局异常处理器完美集成
- ✅ 简化 RESTful API 的状态管理
🔧 注解属性
属性 | 类型 | 说明 | 必需 |
---|---|---|---|
value / code | HttpStatus | HTTP 状态码枚举值 | ✅ |
reason | String | 状态码的原因短语 | ❌ |
💡 使用方式
1. 在控制器方法上使用
@RestController
@RequestMapping("/api/users")
public class UserController {@GetMapping("/{id}")@ResponseStatus(HttpStatus.OK)public User getUser(@PathVariable Long id) {return userService.findById(id);}@PostMapping@ResponseStatus(HttpStatus.CREATED)public User createUser(@RequestBody User user) {return userService.save(user);}@DeleteMapping("/{id}")@ResponseStatus(HttpStatus.NO_CONTENT)public void deleteUser(@PathVariable Long id) {userService.deleteById(id);}
}
2. 在异常类上使用
@ResponseStatus(value = HttpStatus.NOT_FOUND, reason = "用户不存在")
public class UserNotFoundException extends RuntimeException {public UserNotFoundException(String message) {super(message);}
}@ResponseStatus(value = HttpStatus.BAD_REQUEST, reason = "请求参数无效")
public class InvalidRequestException extends RuntimeException {public InvalidRequestException(String message) {super(message);}
}
3. 在全局异常处理器中使用
@RestControllerAdvice
public class GlobalExceptionHandler {@ExceptionHandler(DataIntegrityViolationException.class)@ResponseStatus(HttpStatus.CONFLICT)public ErrorResponse handleDataIntegrityViolation(DataIntegrityViolationException ex) {return new ErrorResponse("CONFLICT", "数据完整性冲突", ex.getMessage());}@ExceptionHandler(MethodArgumentNotValidException.class)@ResponseStatus(HttpStatus.BAD_REQUEST)public ErrorResponse handleValidationException(MethodArgumentNotValidException ex) {return new ErrorResponse("VALIDATION_ERROR", "参数验证失败", ex.getMessage());}
}
🚀 实际应用场景
场景 1:RESTful API 设计
@RestController
@RequestMapping("/api/products")
public class ProductController {@GetMapping@ResponseStatus(HttpStatus.OK)public List<Product> getAllProducts() {return productService.findAll();}@GetMapping("/{id}")@ResponseStatus(HttpStatus.OK)public Product getProduct(@PathVariable Long id) {Product product = productService.findById(id);if (product == null) {throw new ProductNotFoundException("产品不存在");}return product;}@PostMapping@ResponseStatus(HttpStatus.CREATED)public Product createProduct(@Valid @RequestBody Product product) {return productService.save(product);}@PutMapping("/{id}")@ResponseStatus(HttpStatus.OK)public Product updateProduct(@PathVariable Long id, @Valid @RequestBody Product product) {return productService.update(id, product);}@DeleteMapping("/{id}")@ResponseStatus(HttpStatus.NO_CONTENT)public void deleteProduct(@PathVariable Long id) {productService.deleteById(id);}
}
场景 2:自定义业务异常
// 业务异常定义
@ResponseStatus(value = HttpStatus.NOT_FOUND, reason = "订单不存在")
public class OrderNotFoundException extends RuntimeException {public OrderNotFoundException(String orderId) {super("订单 " + orderId + " 不存在");}
}@ResponseStatus(value = HttpStatus.FORBIDDEN, reason = "权限不足")
public class InsufficientPermissionException extends RuntimeException {public InsufficientPermissionException(String message) {super(message);}
}// 控制器使用
@RestController
@RequestMapping("/api/orders")
public class OrderController {@GetMapping("/{orderId}")public Order getOrder(@PathVariable String orderId, @RequestHeader("Authorization") String token) {// 权限检查if (!hasPermission(token)) {throw new InsufficientPermissionException("用户权限不足");}// 订单查找Order order = orderService.findByOrderId(orderId);if (order == null) {throw new OrderNotFoundException(orderId);}return order;}
}
⚠️ 注意事项
1. reason 属性的限制
// ❌ 不推荐:使用 reason 属性会清空响应体
@ResponseStatus(value = HttpStatus.BAD_REQUEST, reason = "参数错误")
public class BadRequestException extends RuntimeException {// 这种方式会调用 response.sendError(),清空响应体
}// ✅ 推荐:不使用 reason,在异常处理器中处理
@ResponseStatus(HttpStatus.BAD_REQUEST)
public class BadRequestException extends RuntimeException {public BadRequestException(String message) {super(message);}
}@RestControllerAdvice
public class GlobalExceptionHandler {@ExceptionHandler(BadRequestException.class)@ResponseStatus(HttpStatus.BAD_REQUEST)public ErrorResponse handleBadRequest(BadRequestException ex) {return new ErrorResponse("BAD_REQUEST", "请求参数错误", ex.getMessage());}
}
2. 与 ResponseEntity 的区别
// 使用 @ResponseStatus(简单场景)
@GetMapping("/simple")
@ResponseStatus(HttpStatus.OK)
public String getSimpleData() {return "简单数据";
}// 使用 ResponseEntity(复杂场景)
@GetMapping("/complex")
public ResponseEntity<ApiResponse<String>> getComplexData() {ApiResponse<String> response = new ApiResponse<>();response.setData("复杂数据");response.setTimestamp(LocalDateTime.now());return ResponseEntity.ok().header("Custom-Header", "value").body(response);
}
3. 状态码优先级
@RestController
public class PriorityController {@GetMapping("/priority")@ResponseStatus(HttpStatus.OK) // 方法级别的状态码public ResponseEntity<String> getData() {// ResponseEntity 的状态码会覆盖 @ResponseStatusreturn ResponseEntity.status(HttpStatus.CREATED).body("数据创建成功");}
}
🔍 最佳实践
1. 统一异常处理
@RestControllerAdvice
public class GlobalExceptionHandler {@ExceptionHandler(ValidationException.class)@ResponseStatus(HttpStatus.BAD_REQUEST)public ErrorResponse handleValidation(ValidationException ex) {return ErrorResponse.builder().code("VALIDATION_ERROR").message("参数验证失败").details(ex.getErrors()).timestamp(LocalDateTime.now()).build();}@ExceptionHandler(ResourceNotFoundException.class)@ResponseStatus(HttpStatus.NOT_FOUND)public ErrorResponse handleNotFound(ResourceNotFoundException ex) {return ErrorResponse.builder().code("RESOURCE_NOT_FOUND").message("资源不存在").details(ex.getMessage()).timestamp(LocalDateTime.now()).build();}
}
2. 状态码枚举使用
public enum ApiStatus {SUCCESS(HttpStatus.OK, "操作成功"),CREATED(HttpStatus.CREATED, "创建成功"),NO_CONTENT(HttpStatus.NO_CONTENT, "删除成功"),BAD_REQUEST(HttpStatus.BAD_REQUEST, "请求参数错误"),UNAUTHORIZED(HttpStatus.UNAUTHORIZED, "未授权"),FORBIDDEN(HttpStatus.FORBIDDEN, "权限不足"),NOT_FOUND(HttpStatus.NOT_FOUND, "资源不存在"),INTERNAL_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, "服务器内部错误");private final HttpStatus httpStatus;private final String message;ApiStatus(HttpStatus httpStatus, String message) {this.httpStatus = httpStatus;this.message = message;}// getter 方法...
}
📊 总结
@ResponseStatus
注解是 Spring 框架中管理 HTTP 响应状态的重要工具:
- 🎯 适用场景:简单的状态码设置、异常处理、RESTful API 设计
- ⚡ 优势:代码简洁、声明式配置、易于维护
- ⚠️ 限制:reason 属性会清空响应体、灵活性不如 ResponseEntity
- 🔧 建议:结合全局异常处理器使用,避免使用 reason 属性
通过合理使用 @ResponseStatus
注解,可以让你的 Spring Boot 应用具有更好的 API 设计和错误处理机制。
厦门工学院人工智能创作坊 – 郑恩赐
2025 年 10 月 1 日