- 发布日期
Spring Boot:全局异常处理
- 作者
- 姓名
- 缘
- 社交账号
文章目录
为什么需要统一异常处理
项目运行过程中,Controller、Service、Mapper、数据库都可能出现异常。
如果不处理,Spring Boot 默认可能返回:
{
"timestamp": "...",
"status": 500,
"error": "Internal Server Error",
"path": "/emps"
}
但项目已经约定统一 Result 响应格式,因此默认异常响应不符合接口规范。
每个Controller都写try-catch的问题
可以直接在 Controller 中捕获异常:
@GetMapping("/{id}")
public Result getInfo(@PathVariable Integer id) {
try {
Emp emp = empService.getInfo(id);
return Result.success(emp);
} catch (Exception e) {
return Result.error("对不起,服务器异常,请稍后重试");
}
}
但如果每个接口都这样写,会产生大量重复代码,Controller 越来越臃肿。
全局异常处理器
更合理的方式是让异常统一交给全局处理器:
Controller
↓
Service
↓
Mapper
↓
Exception
↓
全局异常处理器
↓
统一Result
课程示例:
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler
public Result handleException(Exception e) {
log.error("全局异常处理器, 拦截到异常", e);
return Result.error("对不起,服务器异常,请稍后重试");
}
}
@RestControllerAdvice
课程给出的关系:
@RestControllerAdvice
=
@ControllerAdvice
+
@ResponseBody
它适合前后端分离项目,可以让异常处理方法的返回值直接作为 HTTP 响应体。
@ExceptionHandler
@ExceptionHandler 声明当前方法用于处理异常。
课程示例直接处理通用的:
Exception
当 Controller 调用链中的异常没有被处理时,就可以进入全局异常处理器。
统一日志与响应
全局处理器中保留异常日志:
log.error("全局异常处理器, 拦截到异常", e);
前端则得到统一、友好的错误结果:
{
"code": 0,
"msg": "对不起,服务器异常,请稍后重试",
"data": null
}
这样业务 Controller 无需反复写 try-catch,同时异常响应格式也能保持统一。