简介
SpringMVC的处理器拦截器,类似于Servlet开发中的过滤器Filter,用于处理器进行预处理和后处理。
应用场景
1、日志记录,可以记录请求信息的日志,以便进行信息监控、信息统计等。
2、权限检查:如登陆检测,进入处理器检测是否登陆,如果没有直接返回到登陆页面。
3、性能监控:典型的是慢日志。
HandlerInterceptor
public interface HandlerInterceptor {

/**
  *业务请求处理器请求之前被调用(Controller 的RequestMapping之前被调用)
  *
  */
boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
		throws Exception;

 /**
  *业务请求处理器处理完成后调用(Controler 返回时调用),生成视图之前执行
  *
  */
void postHandle(
		HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
		throws Exception;

 /**
  *在DispatcherServlet完全处理完请求之后被调用,可用于清理资源
  *
  */
void afterCompletion(
		HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
		throws Exception;

}
测试demo如下:
TestInterceptor

public class TestInterceptor implements HandlerInterceptor {
/**
*业务请求处理器处理之前调用 (注意:如果此处的方法返回false,请求被拦截不再往下走了,不会进入Controller)
*
/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println(“test 中的 preHandle方法调用”);
return true;
}
/
*业务请求处理器处理完成后调用(Controler 返回时调用),生成视图之前执行
*
/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("test 中的postHandle 方法调用 ");
}
/
*在DispatcherServlet完全处理完请求之后被调用,可用于清理资源
*
**/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("test 中的afterCompletion方法调用 ");
}
}

TestInterceptor 1

public class TestInterceptor1 implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("test1 中的 preHandle方法调用");
        return true;
    }
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("test1 中的postHandle 方法调用 ");
    }
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("test1 中的afterCompletion方法调用 ");
    }
}

TestInterceptor 2

public class TestInterceptor2 implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("test2 中的 preHandle方法调用");
        return true;
    }
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("test2 中的postHandle 方法调用 ");
    }
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("test2 中的afterCompletion方法调用 ");
    }
}

在spring MVC 相关配置文件拦截器的相关配置信息如下

<!--自定义拦截器(这里的配置顺序将是拦截器执行顺序)-->    
     <mvc:interceptors>
            <mvc:interceptor>
                <mvc:mapping path="/**"/>
                <bean class="com.zstimes.interceptor.TestInterceptor"/>
            </mvc:interceptor>
            <mvc:interceptor>
                <mvc:mapping path="/**"/>
                <bean class="com.zstimes.interceptor.TestInterceptor1"/>
            </mvc:interceptor>
            <mvc:interceptor>
                <mvc:mapping path="/**"/>
                <bean class="com.zstimes.interceptor.TestInterceptor2"/>
            </mvc:interceptor>
        </mvc:interceptors>

测试输出结果如下:

test 中的 preHandle方法调用
    test1 中的 preHandle方法调用
    test2 中的 preHandle方法调用
    ###########Controller 测试方法被调用#############
    test2 中的postHandle 方法调用 
    test1 中的postHandle 方法调用 
    test 中的postHandle 方法调用 
    test2 中的afterCompletion方法调用 
    test1 中的afterCompletion方法调用 
    test 中的afterCompletion方法调用

仔细查看上述输出结果可以知道,preHandler在请求处理器处理之前被调用,处理完成以后在生成视图之前执行调用postHand方法,在DispatcherServlet完全处理完请求之后调用afterCompletion,可用于清理资源。
如果我将TestInterceptor1类中的preHandler方法,返回false会怎么样呢,输出结果如下:

test 中的 preHandle方法调用
test1 中的 preHandle方法调用
test 中的afterCompletion方法调用

通过上述结果可以知道如果TestInterceptor1中的preHandler方法返回false,那么TestInterceptor1拦截器以后的方法将被拦截不在执行,包括Controller中的处理的Action(如果处理类的不执行了,所有拦截器那么postHandle方法也不在执行),但是在TestInterceptor1拦截器之前的afterCompletion方法会执行。
分析springmvc源码可以到拦截器是按照链式的设计模式执行的下编文章会介绍到。