Spring MVC 拦截器

参考以下博文:

http://jinnianshilongnian.iteye.com/blog/1670856

http://www.blogjava.net/wmcoo/articles/333752.html

http://www.blogjava.net/atealxt/archive/2009/09/20/spring_mvc_annotation_interceptor_gae.html

http://my.oschina.net/boonya/blog/92077

spring mvc 可以采用实现HandlerInterceptor 接口 或 继承HandlerInterceptorAdapter类的方法实现。

app-servlet.xml的配置相同:

<!-- 拦截器 -->
    <mvc:interceptors>
        <bean class="cwz.interceptor.SysInterceptor" />
        <mvc:interceptor>
            <mvc:mapping path="/edit.html"/>
            <bean class="cwz.interceptor.UserInterceptor"></bean>
        </mvc:interceptor>
    </mvc:interceptors>

其中

SysInterceptor   是系统级的拦截器
UserInterceptor  是作用于path="/edit.html"请求的拦截器

SysInterceptor实现了HandlerInterceptor 接口;UserInterceptor继承自HandlerInterceptorAdapter类,并重写了preHandle方法:

package cwz.interceptor;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class SysInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception {
        System.out.println("test interceptor sysinterceptor_preHandle");
        System.out.println(request.getRequestURL() + "-" + request.getRequestURI());
        return true;  //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object o, ModelAndView modelAndView) throws Exception {
        System.out.println("test interceptor sysinterceptor_postHandle");
        //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object o, Exception e) throws Exception {
        //To change body of implemented methods use File | Settings | File Templates.
        System.out.println("test interceptor sysinterceptor_afterCompletion");
    }
}

UserInterceptor.java

package cwz.interceptor;

import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Created By cwz
 * Date: 14-7-28 下午3:03
 * <p/>
 * Introduction :
 */
public class UserInterceptor extends HandlerInterceptorAdapter {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("---------UserInterceptor.preHandle-----------");
        return false;
    }
}

说明:
发起请求,进入拦截器链,运行所有拦截器的preHandle方法
1.当preHandle方法返回false时,从当前拦截器往回执行所有拦截器的afterCompletion方法,再退出拦截器链。
2.当preHandle方法全为true时,执行下一个拦截器,直到所有拦截器执行完。再运行被拦截的Controller。然后进入拦截器链,运行所有拦截器的postHandle方法,完后从最后一个拦截器往回执行所有拦截器的afterCompletion方法.
当有拦截器抛出异常时,会从当前拦截器往回执行所有拦截器的afterCompletion方法.

结合本例,由于UserInterceptor 的 preHandle方法返回false,故执行流程应该是

SysInterceptor.preHandle()——UserInterceptor.preHandle()——SysInterceptor.afterCompletion()

打印的结果:

test interceptor sysinterceptor_preHandle
http://localhost:8080/edit.html-/edit.html
---------UserInterceptor.preHandle-----------
test interceptor sysinterceptor_postHandle
test interceptor sysinterceptor_afterCompletion

若返回true,则执行结果:

test interceptor sysinterceptor_preHandle
http://localhost:8080/edit.html-/edit.html
---------UserInterceptor.preHandle-----------
test interceptor sysinterceptor_postHandle
test interceptor sysinterceptor_afterCompletion

-------------------------------------------------------------------------------------------------------------

引用http://jinnianshilongnian.iteye.com/blog/1670856 中的说明及流程图:

我们可能注意到拦截器一个有3个回调方法,而一般的过滤器Filter才两个,这是怎么回事呢?马上分析。

preHandle预处理回调方法,实现处理器的预处理(如登录检查),第三个参数为响应的处理器(如我们上一章的Controller实现);

     返回值:true表示继续流程(如调用下一个拦截器或处理器);

             false表示流程中断(如登录检查失败),不会继续调用其他的拦截器或处理器,此时我们需要通过response来产生响应;

postHandle后处理回调方法,实现处理器的后处理(但在渲染视图之前),此时我们可以通过modelAndView(模型和视图对象)对模型数据进行处理或对视图进行处理,modelAndView也可能为null。

afterCompletion整个请求处理完毕回调方法,即在视图渲染完毕时回调,如性能监控中我们可以在此记录结束时间并输出消耗时间,还可以进行一些资源清理,类似于try-catch-finally中的finally,但仅调用处理器执行链中preHandle返回true的拦截器的afterCompletion

正常流程:


中断流程:






Spring MVC 拦截器,古老的榕树,5-wow.com

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。