SpringBoot如何处理异常
在 Spring Boot 中,异常处理有多种方式,通常建议统一处理异常,使接口返回结构一致。下面按常用程度和最佳实践来讲解。
一、使用 @ControllerAdvice + @ExceptionHandler(✅ 最推荐)
这是 全局异常处理 的标准方式。
1️⃣ 定义统一返回结构
public class Result {
private int code;
private String message;
private T data;
public Result(int code, String message, T data) {
this.code = code;
this.message = message;
this.data = data;
}
public static Result success(T data) {
return new Result<>(200, "success", data);
}
public static Result error(int code, String message) {
return new Result<>(code, message, null);
}
}
2️⃣ 自定义业务异常
public class BusinessException extends RuntimeException {
private int code;
public BusinessException(int code, String message) {
super(message);
this.code = code;
}
public int getCode() {
return code;
}
}
3️⃣ 全局异常处理类
@RestControllerAdvice
public class GlobalExceptionHandler {
// 处理自定义异常
@ExceptionHandler(BusinessException.class)
public Result handleBusinessException(BusinessException e) {
return Result.error(e.getCode(), e.getMessage());
}
// 处理空指针等运行时异常
@ExceptionHandler(RuntimeException.class)
public Result handleRuntimeException(RuntimeException e) {
return Result.error(500, "系统异常:" + e.getMessage());
}
// 处理参数校验异常(@Valid)
@ExceptionHandler(MethodArgumentNotValidException.class)
public Result handleValidException(MethodArgumentNotValidException e) {
String message = e.getBindingResult()
.getFieldError()
.getDefaultMessage();
return Result.error(400, message);
}
}
二、在 Controller 中局部处理异常
适用于某个 Controller 特有异常。
@RestController
@RequestMapping("/user")
public class UserController {
@ExceptionHandler(IllegalArgumentException.class)
public Result handleIllegalArgument(IllegalArgumentException e) {
return Result.error(400, e.getMessage());
}
}
⚠️ 不推荐大规模使用,不利于统一管理。
三、参数校验异常(@Valid / @Validated)
1️⃣ DTO
public class UserDTO {
@NotBlank(message = "用户名不能为空")
private String username;
@Min(value = 1, message = "年龄必须大于0")
private Integer age;
}
2️⃣ Controller
@PostMapping("/save")
public Result save(@Valid @RequestBody UserDTO dto) {
return Result.success(null);
}
异常会被 MethodArgumentNotValidException 捕获。
四、404 / 500 等错误统一处理(可选)
方式一:配置文件
spring:
mvc:
throw-exception-if-no-handler-found: true
web:
resources:
add-mappings: false
这样 404 会抛异常,可被 @ExceptionHandler 捕获。
五、异常处理的执行顺序(面试常问)
- Controller 内部 @ExceptionHandler
- @ControllerAdvice 中的 @ExceptionHandler
- Spring 默认异常机制(BasicErrorController)
六、最佳实践总结 ✅
✅ 使用 @RestControllerAdvice 做全局异常处理
✅ 自定义 BusinessException 区分业务异常
✅ 统一返回结构(code / message / data)
✅ 参数校验异常单独处理
✅ 不要直接返回 Exception 堆栈给前端
如果你愿意,我也可以帮你:
- ✅ 设计一套 真实项目的异常体系
- ✅ 结合 Spring Security / JWT 处理异常
- ✅ 给你一个 完整可运行的 Demo
你现在是学习阶段还是已经在做项目?