在Spirng MVC中,拦截器Interceptor是十分重要也相当常用的。它可以拦截用户的请求并在其前后进行相应的处理,从而使业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高开发的效率。
Spring MVC拦截器一般在需要统一进行处理的时候进行使用。
举几个例子:
1.日志记录 2.权限检查 3.编码修改等等。
看到这里,是不是觉得很熟悉呢?Spring MVC拦截器和Spring AOP的作用基本相似,他们都是基于AOP的思想进行封装的。所以,可以使用AOP思想的地方,比如事务管理,权限管理,日志管理,安全管理等等和业务逻辑关系并不是非常密切的部分,都可以使用Spring MVC拦截器。
Spring MVC拦截器如何使用:
分为三个步骤:
1.实现HandlerInterceptor接口
2.将类注册进Spring MVC容器中。
3.设置拦截规则
例子:
我们有这么一个Controller,是可以正确运行的。
@Controller
public class TestConrtoller {
@RequestMapping(value = "/hello", method = RequestMethod.GET)
public String hello(Model model) {
System.out.println("Conrtoller");
model.addAttribute("msg", "message from controller");
return "index";
}
}
public class TestInterceptor implements HandlerInterceptor{
public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
throws Exception {
System.out.println("afterCompletion");
}
public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
throws Exception {
System.out.println("postHandle");
}
public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {
System.out.println("preHandle");
return true;
}
}
需要增加对servlet api的依赖。
我们在这里简单的输出一些信息。
然后是第二个步骤:注册进Spring MVC容器。
在DispatcherServlet的加载的文件中增加:
<mvc:interceptors>
<bean id = "testInterceptor" class = "springmvc.web.interceptor.TestInterceptor"></bean>
</mvc:interceptors>
结果如下:
很显然,和我们的预期想的一样。
方法解释:
/*
* 在整个请求结束之后,也就是在DispatcherServlet渲染了对应的视图之后执行
* 主要作用是用于进行资源清理工作的
*/
public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
throws Exception {
System.out.println("afterCompletion");
}
/*
* 当前请求进行处理之后,也就是Controller方法调用之后执行
* 在DispatcherServlet进行视图返回渲染之前被调用
* 可以在这个方法中对Controller处理之后的ModelAndView对象进行操作。
*/
public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
throws Exception {
System.out.println("postHandle");
}
/*
* 在请求处理之前进行调用
* 可以在这个方法中进行一些前置初始化操作或者是对当前请求的一个预处理,也可以在这个方法中进行一些判断来决定请求是否要继续进行下去。
* 当它返回为false 时,表示请求结束,后续的Interceptor和Controller都不会再执行;当返回值为true 时就会继续调用下一个Interceptor的preHandle方法
* 如果已经是最后一个Interceptor的时候就会是调用当前请求的Controller方法
*/
public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {
System.out.println("preHandle");
return true;
}
如果我们希望只在某些请求才进行拦截,应该怎么设置呢?
这也就是第三个步骤,设置拦截规则:
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/hello" />
<bean class="springmvc.web.interceptor.TestInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
设置mapping标签就可以设置拦截规则了,需要注意的是,mapping标签一定要写在bean标签的前面,否则会报错。
Spring MVC中的Interceptor 是链式的调用的,在一个应用中或者说是在一个请求中可以同时存在多个Interceptor。
那如果是多个Interceptor的话执行顺序是怎么样的呢?
按照这个流程来,就像公路行驶的一样,pre和post,after的关系,过去和回来是反过来先调用的。
用好Interceptor,就可以非常容易的完成权限管理,日志管理。
除了实现HandlerInterceptor接口之外,还可以实现WebRequestInterceptor接口,大同小异,对于后面的配置以及拦截规则都是一样的。