简介
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源码可以到拦截器是按照链式的设计模式执行的下编文章会介绍到。