典型用法
为某个接口指定固定的 HTTP 状态码(如创建成功返回 201)
当该方法执行成功时,HTTP 响应状态码会是 201 Created。
适用于不需要动态控制状态码的场景。
@PostMapping("/users")
@ResponseStatus(HttpStatus.CREATED)
public User createUser(@RequestBody User user) {
return userService.save(user);
}
抛出自定义异常时自动设置 HTTP 状态码(如资源未找到返回 404)
当抛出 ResourceNotFoundException 时,Spring 会自动将其映射为 404 Not Found 响应。非常适合统一异常处理机制。
@ResponseStatus(HttpStatus.NOT_FOUND)
public class ResourceNotFoundException extends RuntimeException {
public ResourceNotFoundException(String message) {
super(message);
}
}
@GetMapping("/users/{id}")
public User getUserById(@PathVariable Long id) {
return userService.findById(id).orElseThrow(() -> new ResourceNotFoundException("User not found"));
}
结合 @ControllerAdvice 实现全局异常处理
在结合 @ControllerAdvice 实现全局异常处理时,通常不会直接使用 @ResponseStatus 注解来设置响应状态码,而是通过返回值类型 ResponseEntity 或其他封装方式来显式控制 HTTP 状态码和响应体内容。
@ControllerAdvice
public class GlobalExceptionHandler {
// 处理资源未找到异常
@ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity<ErrorResponse> handleResourceNotFound(ResourceNotFoundException ex) {
ErrorResponse error = new ErrorResponse("RESOURCE_NOT_FOUND", ex.getMessage());
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(error);
}
// 处理参数校验异常
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<ErrorResponse> handleValidationExceptions(MethodArgumentNotValidException ex) {
Map<String, String> errors = new HashMap<>();
ex.getBindingResult().getAllErrors().forEach(error -> {
String field = ((FieldError) error).getField();
String message = error.getDefaultMessage();
errors.put(field, message);
});
ErrorResponse error = new ErrorResponse("VALIDATION_ERROR", errors);
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(error);
}
// 处理所有其他异常
@ExceptionHandler(Exception.class)
public ResponseEntity<ErrorResponse> handleGeneralException(Exception ex) {
ErrorResponse error = new ErrorResponse("INTERNAL_SERVER_ERROR", "An unexpected error occurred");
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(error);
}
}
指定响应体内容(不推荐)
虽然 @ResponseStatus 可以设置 reason 属性,但不推荐直接通过注解设置响应体内容,因为这会导致响应格式不一致。
@ResponseStatus(value = HttpStatus.FORBIDDEN, reason = "Access denied")
public class AccessDeniedException extends RuntimeException {
}