一、先来看一个需求
Spring MVC也可以使用拦截器对请求进行拦截处理,用户可以自定义拦截器来实现特定的功能,比如对临时文件的清除,或者对某些ip地址进行拦截器.
二、springMVC自定义拦截器介绍
(1)需要实现一个接口 HandlerInterceptor.
(2)有三个方法需要我们重写
preHandlerO.在目标方法执行之前被调用
postHandleO:在目标方法执行后在被调用
afterCompletion0:在所有的任务完毕后,再调用,比如页面渲染完毕后在调用.
三、入门示例
1、在springMVC的配置文件配置拦截器
<!-- 配置拦截器-->
<mvc:interceptors>
<ref bean="myInterceptor"/>
</mvc:interceptors>
2、 自定义一个拦截器,实现接口HandlerInterceptor,并重写这三个方法
//交给springMVC管理
@Component
public class MyInterceptor implements HandlerInterceptor {
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("preHandle....");
return true;
}
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle....");
}
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("afterCompletion....");
}
}
3、写一个测试handler
@Controller
public class InterceptorTestHandler {
@RequestMapping(value = "/testInterceptor")
public String testInterceptor() {
System.out.println("调用了test方法");
return "success";
}
@RequestMapping(value = "/testInterceptor2")
public String testInterceptor2() {
System.out.println("调用了test2方法");
return "success";
}
}
4、写一个测试页面
<body>
<h1>test01</h1>
<a href="testInterceptor">测试拦截器01</a>
<h1>test02</h1>
<a href="testInterceptor2">测试拦截器02</a>
</body>
5、效果
可以看出,拦截器方法的执行顺序 preHandler >目标方法>postHandler>afterCompletion
四、拦截器的细节
1、如果preHandle方法_返回false,则不会再执行目标方法.实际上可以在此响应请求返回给页面
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("preHandle....");
String mess = "炸弹";
if(mess.equals("炸弹")){
request.getRequestDispatcher("/WEB-INF/pages/error.jsp").forward(request,response);
return false;
}
else {
return true;
}
}
2.说明:postHandle 在目标方法被执行之后执行.可以在方法中访问到目标方法返回ModelAndView对象 (例如可以改变这个MondelAndView的去向)
在postHandle中,做二次处理
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
modelAndView.getView();
modelAndView.setView();
System.out.println("postHandle....");
}
3、若preHandle 返回true,则afterCompletion 方法在渲染视图之后被执行
若preHandle 返回false,则afterCompletion方法不会被调用
4、也可以在配置拦截器时,指定该拦截器对某个请求生效,其它请求不生效
<mvc:mapping></mvc:mapping>
<!-- 配置拦截器-->
<!-- <mvc:mapping></mvc:mapping> 表示被配置的拦截器只对指定路径的目标方法有效-->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/testInterceptor2"/>
<ref bean="myInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
5、排除掉某些请求<mvc:exclude-mapping path="/test"/>
6、多个拦截器时,如何拦截器中的方法如何执行
简单案例:
1、配置两个拦截器
<!-- 配置拦截器-->
<!-- <mvc:mapping></mvc:mapping> 表示被配置的拦截器只对指定路径的目标方法有效-->
<mvc:interceptors>
<ref bean="myInterceptor"/> //即示意图中的A拦截器
<ref bean="multiInterceptor"/> //即示意图中的B拦截器
</mvc:interceptors>
2、复制刚刚案例的拦截器(新建一个拦截器multiInterceptor),将输出语句加多一个2(入门示例)
3、点击请求,看控制台效果
7、多拦截器时, 还需要注意
(1)如果在第一个拦截器的preXxx方法返回false , 后面的代码统统不执行了
2)如果在第二个拦截器的prexxx方法返回false,则会执行前一个拦截器的aftefxxx方法,再退出.