溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

SpringMVC 攔截器理解

發(fā)布時間:2020-07-13 21:40:17 來源:網絡 閱讀:771 作者:jtr22 欄目:開發(fā)技術

SpringMVC 配置攔截器

        1. 作為攔截器當然是為了攔截 (這不是廢話嘛) 那攔截是為了干嘛?

            它可以幫我們攔截未登錄用戶   驗證是否登錄、設置日志記錄、統(tǒng)計一些接口訪問量啊

             進行統(tǒng)一異常處理  設置一些數(shù)據(jù)啊 或者計算下應用接口方法執(zhí)行效率啊 等等


        2. 配置攔截器

                由于用的是SpringMVC所以要知道 它是有個統(tǒng)一的 DispatcherServlet 控制器,

            所以就不用傳統(tǒng)的bean方式了,人家給我們提供了其他簡單的方式

                      

            如下所示:  (我設置了三個方便測試用的)

                <!--攔截器 -->

                <mvc:interceptors>

                        <!--多個攔截器,順序執(zhí)行 -->

                        <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 攔截器需要實現(xiàn) HandlerInterceptor 接口,它有三個方法:

              

            (1) preHandle方法 

                    該方法將在Controller處理之前進行調用,SpringMVC中的Interceptor攔截器是鏈式的,

                    可以同時存在,多個Interceptor,然后SpringMVC會根據(jù)聲明的前后順序一個接一個的

                    執(zhí)行,而且所有的Interceptor中的preHandle方法都會在 Controller方法調用之前調用。

                    SpringMVC的這種Interceptor鏈式結構也是可以進行中斷的,這種中斷方式是令                                  preHandle的返回值為false,當preHandle的返回值為false的時候整個請求就結束了。


            (2) postHandle 方法

        這個方法只會在當前這個Interceptor的preHandle方法返回值為true的時候才會執(zhí)行。

      postHandle是進行處理器攔截用的,它的執(zhí)行時間是在處理器進行處理之后,

                    也就是在Controller的方法調用之后執(zhí)行,但是它會在DispatcherServlet進行視圖的

                    渲染之前執(zhí)行,也就是說在這個方法中你可以對ModelAndView進行操作,

                    這個方法的鏈式結構跟正常訪問的方向是相反的,

                    也就是說先聲明的Interceptor攔截器該方法反而會后調用,(這句話等下你就會明白了)

                    這跟Struts2里面的攔截器的執(zhí)行過程有點像,

                    只是Struts2里面的intercept方法中要手動的調用ActionInvocation的invoke方法

                    Struts2中調用ActionInvocation的invoke方法就是調用下一個Interceptor

                    或者是調用action,然后要在Interceptor之前調用的內容都寫在調用invoke之前,

                    要在Interceptor之后調用的內容都寫在調用invoke方法之后


    (3) afterCompletion方法

                    請求完成后調用,這時把你要做什么事寫上去,比如 清理資源 



        那么建立的攔截器類:  其他兩個都一樣

        public class LoginHandlerInterceptor implements HandlerInterceptor {


    /***

     *  請求傳送到接口之前調用該方法,如true通過則進入接口請求數(shù)據(jù)

     */

    @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.那么多個攔截器的執(zhí)行過程又是如何的?   


            第二個攔截器不通過的  結果:

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

                LoginHandlerInterceptor2 ------ preHandle

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

            也就是說第二個攔截器不會執(zhí)行他自己之后的兩個方法和postHandle() 方法 ,以及之后的攔截器


            第三個攔截器不通過的  結果:

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

                LoginHandlerInterceptor2 ------ preHandle


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


                LoginHandlerInterceptor2 ------ afterCompletion

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

            也就是說第三個攔截器不會執(zhí)行他自己之后的兩個方法和postHandle() 方法 ,以及之后的攔截器


            當3個攔截器都通過執(zhí)行時:

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

                LoginHandlerInterceptor2 ------ preHandle

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


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

                LoginHandlerInterceptor2 ------ postHandle

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


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

                LoginHandlerInterceptor2 ------ afterCompletion

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

總結下:


        所以是執(zhí)行通過了所有的PreHandle()方法之后 才會執(zhí)行 postHandle() 方法;

        preHandle() 方法如果通過了 則執(zhí)行下一個preHandle(), 不通過則不執(zhí)行;

        然后執(zhí)行 通過 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表示攔截,不向下執(zhí)行

        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問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經查實,將立刻刪除涉嫌侵權內容。

AI