
文章目录
- [第5章:SpringBoot 全局异常处理](#第5章:SpringBoot 全局异常处理)
第5章:SpringBoot 全局异常处理
SpringBoot全局异常介绍
什么是全局异常处理?
- 集中捕获项目中所有未被手动捕获的异常;
- 统一封装成前端可解析的 JSON 格式(如包含错误码、错误信息);
- 替代默认的杂乱错误页面 / 堆栈信息。
为什么需要全局异常处理?
-
格式统一:
- 所有异常返回相同结构(如
{code: 500, msg: "服务器内部错误", data: null}) - 前端无需适配多种错误格式。
- 所有异常返回相同结构(如
-
隐藏细节:
- 避免直接返回堆栈信息(含代码路径等敏感信息)
- 提升安全性。
-
减少冗余:
- 无需在每个 Controller 方法中重复编写
try-catch - 简化代码。
- 无需在每个 Controller 方法中重复编写
-
便于调试:
- 可在异常处理器中统一记录日志
- 快速定位问题。
@ControllerAdvice:
- 标识一个 "全局增强类"
- 作用于所有
@Controller标注的类 - 可用于全局异常处理、全局数据绑定等。
@ExceptionHandler:
- 标注在方法上
- 指定该方法处理哪种类型的异常
- 如
@ExceptionHandler(NullPointerException.class)处理空指针异常
实现流程
- 当 Controller 方法抛出异常且未手动捕获时,异常会被 Spring 框架捕获。
- Spring 会查找标注了
@ControllerAdvice的类中 - 是否有
@ExceptionHandler标注的、匹配该异常类型的方法。 - 找到匹配的方法后,执行该方法
- 将返回值(统一响应格式)返回给前端。
-
定义统一响应结果类(Result)
javapackage com.guslegend.common; import lombok.Data; @Data public class Result <T>{ // 状态码 private Integer code; // 错误信息 private String msg; // 响应数据 private T data; // 成功响应(带数据) public static <T> Result<T> success(T data) { Result<T> result = new Result<>(); result.setCode(200); result.setMsg("success"); result.setData(data); return result; } // 成功响应(无数据) public static <T> Result<T> success() { return success(null); } // 错误响应 public static <T> Result<T> error(Integer code, String msg) { Result<T> result = new Result<>(); result.setCode(code); result.setMsg(msg); result.setData(null); return result; } } -
定义自定义业务异常
javapackage com.guslegend.exception; public class BusinessException extends RuntimeException { // 错误码 private Integer code; // 构造方法:传入错误码和错误信息 public BusinessException(Integer code, String message) { super(message); this.code = code; } // getter public Integer getCode() { return code; } } -
实现全局异常处理器(GlobalExceptionHandler)
javapackage com.guslegend.exception; import com.guslegend.common.Result; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; @ControllerAdvice @Slf4j public class GlobalExceptionHandler { /** * 处理自定义业务异常(优先级最高,先捕获业务异常) */ @ExceptionHandler(BusinessException.class) @ResponseBody // 返回JSON格式 public Result<Void> handleBusinessException(BusinessException e) { log.error("业务异常:{}", e.getMessage()); return Result.error(e.getCode(), e.getMessage()); } /** * 处理系统异常(如空指针、数据库异常等,作为兜底处理) */ @ExceptionHandler(Exception.class) @ResponseBody public Result<Void> handleSystemException(Exception e) { log.error("系统异常:", e); return Result.error(500, "服务器内部错误,请联系管理员"); } } -
在业务中使用异常处理
java@GetMapping("/error/{id}") public Result<String> getUser(@PathVariable Long id) { if (id == 0) { throw new BusinessException(404, "用户不存在"); } // 正常返回 return Result.success("用户信息:" + id); }
查看测试结果

