1. 拦截器的概述
Spring MVC中的拦截器(Interceptor)类似于Servlet中的过滤器(Filter),它主要用于拦截用户请求并作相应的处理。通过拦截器可以对系统进行权限验证、记录请求信息的日志、判断用户是否登录等等模块。
2. 拦截器的定义方法
第一种就是通过实现HandlerInterceptor接口,自定义拦截器类代码如下:
1 public class CustomInterceptor implements HandlerInterceptor { 2 /** 3 * preHandle方法是进行处理器拦截用的,顾名思义,该方法将在Controller处理之前进行调用,SpringMVC中的Interceptor拦截器是链式的,可以同时存在 4 * 多个Interceptor,然后SpringMVC会根据声明的前后顺序一个接一个的执行,而且所有的Interceptor中的preHandle方法都会在 5 * Controller方法调用之前调用。SpringMVC的这种Interceptor链式结构也是可以进行中断的,这种中断方式是令preHandle的返 6 * 回值为false,当preHandle的返回值为false的时候整个请求就结束了。 7 */ 8 9 public boolean preHandle(HttpServletRequest request, 10 HttpServletResponse response, Object handler)throws Exception { 11 //该方法会在控制器方法前执行,其返回值表示是否中断后续操作。当其返回值为true时,表示继续向下执行; 12 //当其返回值为false时,会中断后续的所有操作(包括调用下一个拦截器和控制器类中的方法执行等)。 13 return false; 14 } 15 /** 16 * 这个方法只会在当前这个Interceptor的preHandle方法返回值为true的时候才会执行。postHandle是进行处理器拦截用的,它的执行时间是在处理器进行处理之 17 * 后,也就是在Controller的方法调用之后执行,但是它会在DispatcherServlet进行视图的渲染之前执行,也就是说在这个方法中你可以对ModelAndView进行操 18 * 作。这个方法的链式结构跟正常访问的方向是相反的,也就是说先声明的Interceptor拦截器该方法反而会后调用,这跟Struts2里面的拦截器的执行过程有点像, 19 * 只是Struts2里面的intercept方法中要手动的调用ActionInvocation的invoke方法,Struts2中调用ActionInvocation的invoke方法就是调用下一个Interceptor 20 * 或者是调用action,然后要在Interceptor之前调用的内容都写在调用invoke之前,要在Interceptor之后调用的内容都写在调用invoke方法之后。 21 */ 22 23 public void postHandle(HttpServletRequest request, 24 HttpServletResponse response, Object handler, 25 ModelAndView modelAndView) throws Exception { 26 //该方法会在控制器方法调用之后,且解析视图之前执行。可以通过此方法对请求域中的模型和视图做出进一步的修改。(这里可以去做ThreadLocal中资源的清除。) 27 } 28 /** 29 * 该方法也是需要当前对应的Interceptor的preHandle方法的返回值为true时才会执行。该方法将在整个请求完成之后,也就是DispatcherServlet渲染了视图执行, 30 * 这个方法的主要作用是用于清理资源的,当然这个方法也只能在当前这个Interceptor的preHandle方法的返回值为true时才会执行。 31 */ 32 public void afterCompletion(HttpServletRequest request, 33 HttpServletResponse response, Object handler, 34 Exception ex) throws Exception { 35 //该方法会在整个请求完成,即视图渲染结束之后执行。可以通过此方法实现一些资源清理、记录日志信息等工作。(这里也是去补偿了ThreadLocal中资源的清除) 36 } 37 }
注意:在springboot中就不要配置xml文件了,直接重写WebMvcConfigurerAdapter中的方法:addPathPatterns()用于添加拦截规则, excludePathPatterns()用户排除拦截
在springMVC.xml中需要配置以下的代码:
<!--配置拦截器--> <mvc:interceptors> <!--<bean class="com.ma.interceptor.CustomeInterceptor" />--> <!--拦截器1--> <mvc:interceptor> <!--配置拦截器的作用路径--> <mvc:mapping path="/**"/> <mvc:exclude-mapping path=""/> <!--定义在<mvc:interceptor>下面的表示匹配指定路径的请求才进行拦截--> <bean class="com.ma.interceptor.Intercptor1"/> </mvc:interceptor> <!--拦截器2--> <mvc:interceptor> <mvc:mapping path="/hello"/> <bean class="com.ma.interceptor.Interceptor2"/> </mvc:interceptor> </mvc:interceptors>
上面的代码中,<mvc:interceptors>元素用于配置一组拦截器,基子元素<bean>中定义的是全局拦截器,它会拦截所有的请求;而<mvc:interceptor>元素中定义的是指定路径的拦截器,它会对指定路径下的请求生效。<mvc:interceptor>元素的子元素<mvc:mapping>用于配置拦截器作用的路径,该路径在其属性path 中定义。如上述代码中 path 的属性值“/**” 表示拦截所有路径,“/hello” 表示拦截所有以 “/hello” 结尾的路径。如果在请求路径中包含不需要拦截的内容,还可以通过<mvc:exclude-mapping>元素进行配置。
注意:<mvc:interceptor>中的子元素必须按照上述代码中的配置顺序进行编写,即<mvc:mapping> <mvc:exclude-mapping> <bean>,否则文件会报错。
3. 执行过程
程序先执行preHandle()方法,如果该方法的返回值为true,则程序会继续向下执行处理器中的方法,否则将不再向下执行。
在业务处理器(即控制器Controller类)处理完请求后,会执行postHandle()方法,然后会通过DispatcherServlet向客户端返回响应。
在DispatcherServlet处理完请求后,才会执行afterCompletion()方法。
参考博客:https://blog.csdn.net/zlj1217/article/details/82532510