SpringBoot开发,使用ControllerAdvice全局捕获异常
发布于 作者:苏南大叔 来源:程序如此灵动~

在上一篇文章中,苏南大叔描述了如果使用aspect
切面文件分离验证逻辑的话。同时,也带来了一个小小的问题。那就是异常信息太多了,看起来很复杂不明确,繁杂信息太多。本文描述异常处理的一些方式。
苏南大叔的“程序如此灵动”博客,记录苏南大叔的代码编程经验总结。测试环境:win10
,openjdk@23.0.2
,IntelliJ IDEA 2024.3.4.1
,maven@3.3.2
,spring boot@2.5.4
,java@17
,mysql@5.7.26
。
代码回顾
由于篇幅限制,本文仅以csrf
验证为例,login
验证是同理的。
没有使用aspect
切面文件之前的代码写法及效果:
@PostMapping
public ResponseEntity<?> createUser(@RequestBody User user, HttpServletRequest request) {
//...
try {
validateCsrfToken(request);
return ResponseEntity.ok(userService.createUser(user));
} catch (RuntimeException e) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.getMessage());
}
}
参考文章:
使用aspect
切面文件之后的代码写法及效果:
@Before("execution(* com.example.demo.controller.UserController.*(..))")
public void checkCsrfToken() {
//...
if (sessionCsrfToken == null || !sessionCsrfToken.equals(requestCsrfToken)) {
throw new RuntimeException("CSRF token 验证失败");
}
}
这主要是因为aspect
相关验证,使用Before
定义在Controller
方法之前执行了。相关方法内的异常捕获逻辑,并不能做到捕获。
参考文章:
全局异常捕获
基于springboot
的aop
框架,建立一个ControllerAdvice
类型的文件。
记得安装依赖spring-boot-starter-aop
。
src/main/java/com/example/demo/controller/GlobalExceptionHandler.java
:
package com.example.demo.controller;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(RuntimeException.class)
public ResponseEntity<String> handleRuntimeException(RuntimeException e) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.getMessage());
}
}
这样就可以像以前一样,简化输出提示了。值得一提的是:这个全局异常捕获的补丁,依然是个搭积木效果。移除这个文件并不会报错,只是效果消失而已。
结语
本文讲述使用aop
中的advice
思想,添加一个全局异常捕获的功能,修改了结果输出内容。更多苏南大叔的java
相关经验文字,请点击:


