Spring MVC中的拦截器(Interceptor)类似于Servlet中的过滤器(Filter),它主要用于拦截用户请求并作相应的处理。例如通过拦截器可以进行权限验证、记录请求信息的日志、判断用户是否登录等。
9.1、拦截器的实现
Spring有两个途径可以实现自己的拦截器。一、通过实现HandlerInterceptor接口,或继承HandlerInterceptor接口的实现类(如HandlerInterceptorAdapter)来定义。二、通过实现WebRequestInterceptor接口,或继承WebRequestInterceptor接口的实现类来定义。
以实现HandlerInterceptor接口方式为例,自定义拦截器类的代码如下:
package intercept; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; public class LoginInterceptor implements HandlerInterceptor { @Override public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3) throws Exception { } @Override public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3) throws Exception { } @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object arg2) throws Exception { HttpSession session=request.getSession(); if(session.getAttribute("username")==null||session.getAttribute("username")=="") return false; else return true; } } |
preHandle(),在Action之前执行的预处理,可以进行编码、安全控制等处理。该方法会在控制器方法前执行,其返回值表示是否中断后续操作。当其返回值为true时,表示继续向下执行;当其返回值为false时,会中断后续的所有操作。接口HandlerInterceptor包含三个方法,每个方法的参数handler对象用来指向下一个拦截器。
postHandle(),在生成View之前执行的后处理,调用了Service并返回ModelAndView,但未进行页面渲染,可以修改ModelAndView,该方法会在控制器方法调用之后,且解析视图之前执行。可以通过此方法对请求域中的模型和视图做出进一步的修改。
afterCompletion(),最后执行的返回处理,这时已经进行了页面渲染,可以进行日志记录、释放资源等处理,该方法会在整个请求完成,即视图渲染结束之后执行。可以通过此方法实现一些资源清理、记录日志信息等工作。
其执行流程如下:

如果有多个拦截器,多个拦截器(假设有两个拦截器Interceptor1和Interceptor2,并且在配置文件中, Interceptor1拦截器配置在前),在程序中的执行流程如下图所示:

从图可以看出,当有多个拦截器同时工作时,它们的preHandle()方法会按照配置文件中拦截器的配置顺序执行,而它们的postHandle()方法和afterCompletion()方法则会按照配置顺序的反序执行。

