在web项目中,拦截器可以用于拦截请求,比较常用的用法是做登陆拦截、权限校验、防重复提交等。
在SpringBoot中使用拦截器也非常的简单,只需要实现HandlerInterceptor接口即可,接口有preHandle、postHandle与afterCompletion这3个方法,分别对应请求的各个时期。
1、preHandle
调用时间:Controller方法处理之前
执行顺序:链式Intercepter情况下,Intercepter按照声明的顺序一个接一个顺序执行
返回结果为true,则会执行2和3过程;若返回false,则中断执行
2、postHandle
调用时间:Controller方法处理完之后,DispatcherServlet进行视图的渲染之前,也就是说在这个方法中你可以对ModelAndView进行操作
执行顺序:链式Intercepter情况下,Intercepter按照声明的顺序倒序执行
3、afterCompletion
调用时间:DispatcherServlet进行视图的渲染之后
执行顺序:链式Intercepter情况下,Intercepter按照声明的顺序倒序执行
一个拦截器A的代码示例:
@Component
public class AInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("A----preHandle");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("A----postHandle");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("A----afterCompletion");
}
}
为了使拦截器生效,我们还需要新增一个配置类。该配置类需要实现WebMvcConfigurer接口:
/**
* web配置
*/
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Autowired
private AInterceptor aInterceptor;
@Autowired
private BInterceptor bInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(aInterceptor)
.addPathPatterns("/**");
registry.addInterceptor(bInterceptor)
.addPathPatterns("/**");
}
}
如代码所示,我们指定拦截器A拦截的url路径为/**
,也就是针对所有请求都进行拦截。这里的pathPatterns就是需要拦截的url路径的地址,支持通配符配置。
可以注意到,我们这里配置了2个拦截器A和B。在一个项目中,是可以存在多个拦截器的,而多个拦截器则会形成一个拦截器链,拦截器链是有顺序的,也就是上文提到的:拦截器的声明顺序。上文代码的拦截器链的声明顺序为A-B。
AB拦截器代码都一样,只是输出标识不一样,下面是一个测试用例用于演示拦截器3个方法的调用顺序:
A----preHandle
B----preHandle
业务逻辑
B----postHandle
A----postHandle
B----afterCompletion
A----afterCompletion
到这里,拦截器的使用就介绍完了。
代码:https://gitee.com/lqccan/blog-demo/tree/master/SpringBoot/interceptor