温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

SpringMVC 拦截器理解

发布时间:2020-07-13 21:40:17 来源:网络 阅读:783 作者:jtr22 栏目:开发技术

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");

}




向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI