Spring MVC 拦截器

   拦截器是Spring MVC中强大的控件,它可以在进入处理器之前做一些操作,或者在处理器完成后进行操作,甚至是在渲染视图后进行操作。

拦截器的定义

  Spring要求处理器的拦截器都要实现接口org.springframe-work.web.servlet. HandlerInterceptor,这个接口定义了3个方法
  •preHandle方法:在处理器之前执行的前置方法,这样Spring MVC可以在进入处理器前处理一些方法了。注意,它将返回一个boolean值,会影响到后面Spring MVC的流程。
  •postHandle方法:在处理器之后执行的后置方法,处理器的逻辑完成后运行它。
  •afterCompletion方法:无论是否产生异常都会在渲染视图后执行的方法。

拦截器的执行流程


  在进入处理器之前或者之后处理一些逻辑,或者在渲染视图之后处理一些逻辑,都是允许的。有时候要自己实现一些拦截器,以加强请求的功能。注意,当前置方法返回false时,就不会再执行后面的逻辑了。在拦截器中可以完成前置方法、后置方法和完成方法的相关逻辑。

开发拦截器

  在开发拦截器之前,要先了解拦截器的设计,拦截器必须实现HandlerInterceptor接口,而Spring也为增强功能而开发了多个拦截器。
注意,当XML配置文件加入了元素<mvc:annotation-driven>或者使用Java配置使用注解@EnableWebMvc时,系统就会初始化拦截器ConversionServiceExposingInterceptor,它是个一开始就被Spring MVC系统默认加载的拦截器,它的主要作用是根据配置在控制器上的注解来完成对应的功能。
  Spring MVC提供公共拦截器HandlerInterceptorAdapter,Spring之所以那么做,是为了提供适配器,就是当只想实现3个拦截器方法中的一到两个时,那么只要继承它,根据需要覆盖掉原有的方法就可以了。
  代码清单15-31:拦截器
package com.ssm.chapter15.interceptor;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class RoleInterceptor extends HandlerInterceptorAdapter {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.err.println("preHandle");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.err.println("postHandle");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.err.println("afterCompletion");
    }

}
  代码清单15-32:配置拦截器(比如dispatcher-servlet.xml)
<mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="/role/*.do"/>
        <bean class="com.ssm.chapter15.interceptor.RoleInterceptor1"/>
    </mvc:interceptor>
</mvc:interceptors>

多个拦截器执行的顺序

编写拦截器RoleInterceptor1 ,RoleInterceptor2 ,RoleInterceptor3
...... 
preHandle1 
preHandle2 
preHandle3 
......控制器逻辑日志...... 
postHandle3 
postHandle2 
postHandle1 
...... 
afterCompletion3 
afterCompletion2 
afterCompletion1 
......
  Spring会先从第一个拦截器开始进入前置方法,这样前置方法是按配置顺序运行的,然后运行处理器的代码,最后运行后置方法。注意,后置方法和完成方法则是按照配置逆序运行的,这和责任链模式的运行顺序是一致的,掌握了责任链模式这个顺序就好理解了。
  有些时候前置方法可能返回false,那么返回false会怎么样呢?将RoleInterceptor2中的前置方法preHandle修改为返回false,然后进行测试,其日志结果如下:
preHandle1 
preHandle2 
afterCompletion1
  注意,当其中的一个preHandle方法返回为false后,按配置顺序,后面的preHandle方法都不会运行了,而控制器和所有的后置方法postHandle也不会再运行。执行过preHandle方法且该方法返回为true的拦截器的完成方法(afterCompletion)会按照配置的逆序运行。 
原文地址:https://www.cnblogs.com/ooo0/p/11107236.html