SpringBoot拦截器的使用
Hi I’m Shendi
SpringBoot拦截器的使用
简介
最近要实现一个全局对象的传递,在接口中直接通过增加函数参数来直接使用的这种方式
之前一直使用的是过滤器,但这种需求过滤器是没有办法实现的,过滤器可以给请求注入字符串,但不能注入对象
例如 User 类,想要的效果如下
public String test(User user) {return user.toString();
}
经过使用,拦截器也不能实现这样的效果…
可以使用addArgumentResolvers来实现,参考 https://sdpro.top/blog/html/article/1047.html
SpringBoot拦截器和Servlet的过滤器类似,相当于基于AOP的函数拦截,拦截器可以用来进行身份验证、日志记录、请求参数处理等。
创建拦截器
有两种方法
- 实现 org.springframework.web.servlet.HandlerInterceptor
- 继承 org.springframework.web.servlet.handler.HandlerInterceptorAdapter
- 这个我用的时候已经被标记弃用了,并且我看实现的AsyncHandlerInterceptor接口,而AsyncHandlerInterceptor实现HandlerInterceptor,所以建议使用第一种
接口代码如下
可以看到接口定义了三个默认行为,分别为如下
名称 | 描述 |
---|---|
preHandle | 在请求处理前执行,可以理解为过滤器的 chain.doFilter 上面部分代码,有一个boolean返回值,返回true则会继续执行,否则不继续执行 |
postHandle | 在请求处理完执行,可以理解为过滤器的 chain.doFilter 后面部分代码 |
afterCompletion | 处理完执行,在postHandle之后。可以理解为finally |
代码如下
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;public class DefaultIntercept implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("pre");return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("post");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("after");}}
配置拦截器
要使拦截器生效,还需要进行以下操作
- 创建类,实现WebMvcConfigurer接口
- 实现addInterceptors函数
- 在函数内使用 registry.addInterceptor 来使拦截器生效
例如
@Configuration
public class WebConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(defaultIntercept()).addPathPatterns("/**");}@Beanpublic DefaultIntercept defaultIntercept() {return new DefaultIntercept();}}
后面的 addPathPatterns
为匹配的规则,具体可以参考文档,/**
就代表全部
运行测试
随便建个接口,试试拦截器效果
@GetMapping("/")
public String get() {System.out.println("接口执行");return "test";
}
请求后控制台输出如下
在pre的时候 return false
看一下结果
可以看到执行了pre后就没有继续执行了
调整优先级
在配置类,添加拦截器的时候可以使用 order
函数指定
registry.addInterceptor(defaultIntercept()).addPathPatterns("/**").order(1);
值越小,优先级越高,不配置默认是0,如果没有指定,那么将按照加入的先后顺序进行拦截
END