2026-04-27-统一功能处理
在之前的学习中,发现了需要有统一的对象 Result ,用来区分 http 的状态码和服务的状态码。
但是,如果每一个方法的结果都要返回指定的 Result 对象,那么就是一个很无聊重复的事情,因此 SpringBoot 设计了一系列的统一功能处理,来解决这类情况
统一请求处理
它一般是用来校验登录状态的,需要设置一个拦截器与注册这个拦截器
拦截器设置
需要实现 HandlerInterceptor 这个接口,里面有这三个方法:preHandle,postHandle,afterCompletion。
其中用的比较多的是 preHandle ,在进入 Controller 层之前就会执行这个方法,可以用来校验登录状态
拦截器注册
这个是需要实现 WebMvcConfigurer 接口,使用 addInterceptors 这个方法来经行注册
private LoginInterceptor loginInterceptor;
private final List<String> excludePathPatterns = List.of(
"/user/login",
"/css/**",
"/js/**",
"/pic/**",
"/test/**"
);
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 注册拦截器
registry.addInterceptor(loginInterceptor)
.addPathPatterns("/**") // 拦截所有请求
.excludePathPatterns(excludePathPatterns); // 排除路径
}统一结果返回
这个是要实现 ResponseBodyAdvice 这个接口,但是需要配合 RestControllerAdvice 注解来使用
注意:是 RestControllerAdvice 而不是 ControllerAdvice,后者是会返回视图对象的地址的,
统一异常处理
它是不需要实现接口,但是它是需要有使用 RestControllerAdvice 和 ExceptionHandler 这两个注解,ExceptionHandler 是放在方法上面的。
异常执行顺序是根据深度来判断优先级的
比如父类
Exception有两个子类Test1Exception和Test2Exception,Test1Exception又有一个子类Test11Exception。 那么Exception深度为 1,Test1Exception和Test2Exception是 2,Test11Exception深度是 3.如果抛出一个
Test1Exception异常,那么它就会判断找父类,找到深度最深(离它最近) 的一个异常
注意:如果统一异常的注解使用 ControllerAdvice 而不是 RestControllerAdvice,那么就会导致抛出异常的时候会出现死循环:抛异常 -- 统一异常处理 -- 返回一个大概率不存在的地址 -- 抛异常