一、什么是拦截器
Spring Web MVC 的处理器拦截器类似于Servlet 开发中的过滤器Filter,用于对处理器进行预处理和后处理。
要编写拦截器必须要实现HandlerInterceptor接口。
二、拦截器实现
1、拦截器的编写
编写两个用于测试的拦截器。
拦截器一:
public class MyIntersector1 implements HandlerInterceptor {
/**
* 该方法在controller方法执行之前调用
* 返回false表示拦截,返回true表示通过。
* 用途:可以用来进行身份验证,权限验证等信息。
*/
@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
System.out.println("MyIntersector1..."+"preHandle");
return true;
}
/**
*该方法在controller方法以及执行但还没有返回时调用
* 用途:对controller返回的数据可以在这里进行处理,比如加入所有页面都有的导航数据。
*/
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
System.out.println("MyIntersector1..."+"postHandle");
}
/**
*该方法在controller方法执行后并且视图返回后调用
* 作用:可以记录controller的异常信息,记录日志,清理资源等。
*/
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
System.out.println("MyIntersector1..."+"afterCompletion");
}
}
拦截器二:
public class MyIntersector2 implements HandlerInterceptor {
/**
* 该方法在controller方法执行之前调用
* 返回false表示拦截,返回true表示通过。
* 用途:可以用来进行身份验证,权限验证等信息。
*/
@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
System.out.println("MyIntersector2..."+"preHandle");
return true;
}
/**
*该方法在controller方法以及执行但还没有返回时调用
* 用途:对controller返回的数据可以在这里进行处理,比如加入所有页面都有的导航数据。
*/
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
System.out.println("MyIntersector2..."+"postHandle");
}
/**
*该方法在controller方法执行后并且视图返回后调用
* 作用:可以记录controller的异常信息,记录日志,清理资源等。
*/
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
System.out.println("MyIntersector2..."+"afterCompletion");
}
}
2、在SpringMVC的配置文件中配置拦截器
第一种方法:针对某种mapping配置拦截器。
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping">
<property name="interceptors">
<list>
<ref bean="handlerInterceptor1"/>
<ref bean="handlerInterceptor2"/>
</list>
</property>
</bean>
<bean id="handlerInterceptor1" class="com.jack.intersector.MyIntersector1"/>
<bean id="handlerInterceptor2" class="com.jack.intersector.MyIntersector2"/>
第二种方式:配置全局的拦截器。
<!--配置全局的拦截器-->
<mvc:interceptors>
<!--多个拦截器顺序执行-->
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.jack.intersector.MyIntersector1" />
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.jack.intersector.MyIntersector2" />
</mvc:interceptor>
</mvc:interceptors>
3、测试分析
(1)MyIntersector1的preHandler方法返回false,MyIntersector2返回true。
第一个拦截器的preHandler方法返回false后第一个拦截器只执行了preHandler方法,其它两个方法没有执行,第二个拦截器的所有方法不执行,且controller也不执行了。
(2)MyIntersector1的preHandler方法返回true,MyIntersector2返回false.
第二个拦截器的preHandler方法返回false后第一个拦截器的postHandler没有执行,第二个拦截器的postHandler和afterCompletion没有执行,且controller也不执行了。
4、总结
(1)preHandle方法按顺序执行,
postHandle和afterCompletion按拦截器配置的逆向顺序执行。
(2)拦截器1放行,拦截器2 preHandle才会执行。
拦截器2 preHandle不放行,拦截器2 postHandle和afterCompletion不会执行。
只要有一个拦截器不放行,postHandle不会执行。
(3)截器1 preHandle不放行,postHandle和afterCompletion不会执行。
拦截器1 preHandle不放行,拦截器2不执行。