在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 demo19