码迷,mamicode.com
首页 > 编程语言 > 详细

SpringMVC 拦截器理解

时间:2016-12-21 21:45:44      阅读:175      评论:0      收藏:0      [点我收藏+]

标签:springmvc 拦截器 登录拦截器

SpringMVC 配置拦截器

        1. 作为拦截器当然是为了拦截 (这不是废话嘛) 那拦截是为了干嘛?

            它可以帮我们拦截未登录用户   验证是否登录、设置日志记录、统计一些接口访问量啊

             进行统一异常处理  设置一些数据啊 或者计算下应用接口方法执行效率啊 等等


        2. 配置拦截器

                由于用的是SpringMVC所以要知道 它是有个统一的 DispatcherServlet 控制器,

            所以就不用传统的bean方式了,人家给我们提供了其他简单的方式

                      

            如下所示:  (我设置了三个方便测试用的)

                <!--拦截器 -->

                <mvc:interceptors>

                        <!--多个拦截器,顺序执行 -->

                        <mvc:interceptor>

                                <mvc:mapping path="/**" />

                                <!-- 表示拦截所有的url,包括子url路径 -->

                                <bean class="com.tz.interceptor.LoginHandlerInterceptor"></bean>

                        </mvc:interceptor>

                        <mvc:interceptor>

                                <mvc:mapping path="/**" />

                                <bean class="com.tz.interceptor.LoginHandlerInterceptor2"></bean>

                                </mvc:interceptor>

                        <mvc:interceptor>    

                                <mvc:mapping path="/**" />

                                <bean class="com.tz.interceptor.LoginHandlerInterceptor3"></bean>

                        </mvc:interceptor>

                </mvc:interceptors>


   

        

         SpringMVC 拦截器需要实现 HandlerInterceptor 接口,它有三个方法:

              

            (1) preHandle方法 

                    该方法将在Controller处理之前进行调用,SpringMVC中的Interceptor拦截器是链式的,

                    可以同时存在,多个Interceptor,然后SpringMVC会根据声明的前后顺序一个接一个的

                    执行,而且所有的Interceptor中的preHandle方法都会在 Controller方法调用之前调用。

                    SpringMVC的这种Interceptor链式结构也是可以进行中断的,这种中断方式是令                                  preHandle的返回值为false,当preHandle的返回值为false的时候整个请求就结束了。


            (2) postHandle 方法

        这个方法只会在当前这个Interceptor的preHandle方法返回值为true的时候才会执行

      postHandle是进行处理器拦截用的,它的执行时间是在处理器进行处理之后,

                    也就是在Controller的方法调用之后执行,但是它会在DispatcherServlet进行视图的

                    渲染之前执行,也就是说在这个方法中你可以对ModelAndView进行操作,

                    这个方法的链式结构跟正常访问的方向是相反的,

                    也就是说先声明的Interceptor拦截器该方法反而会后调用,(这句话等下你就会明白了)

                    这跟Struts2里面的拦截器的执行过程有点像,

                    只是Struts2里面的intercept方法中要手动的调用ActionInvocation的invoke方法

                    Struts2中调用ActionInvocation的invoke方法就是调用下一个Interceptor

                    或者是调用action,然后要在Interceptor之前调用的内容都写在调用invoke之前,

                    要在Interceptor之后调用的内容都写在调用invoke方法之后


    (3) afterCompletion方法

                    请求完成后调用,这时把你要做什么事写上去,比如 清理资源 



        那么建立的拦截器类:  其他两个都一样

        public class LoginHandlerInterceptor implements HandlerInterceptor {


    /***

     *  请求传送到接口之前调用该方法,如true通过则进入接口请求数据

     */

    @Override

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {


System.out.println("LoginHandlerInterceptor ------ preHandle");


                return true;

            }


    @Override

            public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,ModelAndView modelAndView)     throws Exception {


System.out.println("LoginHandlerInterceptor ------ postHandle");

            }


         @Override

            public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)  throws Exception {

System.out.println("LoginHandlerInterceptor ------ afterCompletion");


    }

}



        3.那么多个拦截器的执行过程又是如何的?   


            第二个拦截器不通过的  结果:

                LoginHandlerInterceptor ----------preHandle

                LoginHandlerInterceptor2 ------ preHandle

                LoginHandlerInterceptor ----------afterCompletion

            也就是说第二个拦截器不会执行他自己之后的两个方法和postHandle() 方法 ,以及之后的拦截器


            第三个拦截器不通过的  结果:

                LoginHandlerInterceptor ----------preHandle

                LoginHandlerInterceptor2 ------ preHandle


                LoginHandlerInterceptor3 ------------ preHandle


                LoginHandlerInterceptor2 ------ afterCompletion

                LoginHandlerInterceptor ----------afterCompletion

            也就是说第三个拦截器不会执行他自己之后的两个方法和postHandle() 方法 ,以及之后的拦截器


            当3个拦截器都通过执行时:

                LoginHandlerInterceptor ----------preHandle

                LoginHandlerInterceptor2 ------ preHandle

                LoginHandlerInterceptor3 ------------ preHandle


                LoginHandlerInterceptor3 ---------- postHandle

                LoginHandlerInterceptor2 ------ postHandle

                LoginHandlerInterceptor ---------- postHandle


                LoginHandlerInterceptor3  ---------- afterCompletion

                LoginHandlerInterceptor2 ------ afterCompletion

                LoginHandlerInterceptor ---------- afterCompletion

总结下:


        所以是执行通过了所有的PreHandle()方法之后 才会执行 postHandle() 方法;

        preHandle() 方法如果通过了 则执行下一个preHandle(), 不通过则不执行;

        然后执行 通过 preHandle() 方法的拦截器的 afterCompletion() 方法




我随性写了个登录拦截器 大神勿喷


public class LoginHandlerInterceptor implements HandlerInterceptor {


@Override

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)

throws Exception {

//获取请求的url

        String url = request.getRequestURI();

        System.out.println("LoginHandlerInterceptor ----------preHandle");

        //判断url是否是公开地址,实际使用时应该将公开地址配置在配置文件中,这里公开地址是登录提交的地址

        if(url.indexOf("login") >= 0){

            //如果是登录提交,则放行

            return true;

        }


        HttpSession session = request.getSession();

        //从session中取出用于身份信息

        String username = (String) session.getAttribute("tzUserName");

        if(username != null){

            //身份信息验证通过,放行

            return true;    

        }

        //没有校验通过,表示用户身份需要认证,此时需要跳转到登录页面

        request.getRequestDispatcher("/views/login.jsp").forward(request, response);

        //返回false表示拦截,不向下执行

        return false;

}


@Override

public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

        System.out.println("LoginHandlerInterceptor ----------postHandle");

}


@Override

public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

        System.out.println("LoginHandlerInterceptor ----------afterCompletion");

}




本文出自 “JTR” 博客,请务必保留此出处http://10229180.blog.51cto.com/10219180/1884832

SpringMVC 拦截器理解

标签:springmvc 拦截器 登录拦截器

原文地址:http://10229180.blog.51cto.com/10219180/1884832

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!