典型用法
为某个接口指定固定的 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 {
}