1. 程式人生 > >攔截器、過濾器、監聽器各有什麼作用?

攔截器、過濾器、監聽器各有什麼作用?

這裡是修真院後端小課堂,每篇分享文從

【背景介紹】【知識剖析】【常見問題】【解決方案】【編碼實戰】【擴充套件思考】【更多討論】【參考文獻】

八個方面深度解析後端知識/技能,本篇分享的是:

【攔截器、過濾器、監聽器各有什麼作用?】

 

大家好,我是IT修真院鄭州分院第十期學員,一枚正直純潔善良的JAVA程式設計師。

今天給大家分享一下,修真院官網JAVA任務五,擴充套件思考中的知識點——攔截器、過濾器、監聽器各有什麼作用?

一、背景介紹

     1.過濾器

     依賴於servlet容器。在實現上基於函式回撥,可以對幾乎所有請求進行過濾,但是缺點是一個過濾器例項只能在容器初始化時呼叫一次。使用過濾器的目的是用來做一些過濾操作,獲取我們想要獲取的資料,比如:在過濾器中修改字元編碼;在過濾器中修改HttpServletRequest的一些引數,包括:過濾低俗文字、危險字元等。

     2.攔截器

     依賴於web框架,在SpringMVC中就是依賴於SpringMVC框架。在實現上基於Java的反射機制,屬於面向切面程式設計(AOP)的一種運用。由於攔截器是基於web框架的呼叫,因此可以使用Spring的依賴注入(DI)進行一些業務操作,同時一個攔截器例項在一個controller生命週期之內可以多次呼叫。但是缺點是隻能對controller請求進行攔截,對其他的一些比如直接訪問靜態資源的請求則沒辦法進行攔截處理。 

     3.監聽器

   web監聽器是一種Servlet中的特殊的類,它們能幫助開發者監聽web中的特定事件,實現了javax.servlet.ServletContextListener 介面的伺服器端程式,它也是隨web應用的啟動而啟動,只初始化一次,隨web應用的停止而銷燬。主要作用是:感知到包括request(請求域),session(會話域)和applicaiton(應用程式)的初始化和屬性的變化。

二、知識剖析

    1.攔截器的使用

     專案中使用:編寫實現介面的類+springMVC.xml中配置

   過濾器只需要實現HandlerInterceptor或者WebRequestInterceptor,重寫相應的preHandle(...)、postHandle(...)和afterCompletion(...)方法即可。

     (1)preHandle 方法將在請求處理之前進行呼叫。所以可以在這個方法中進行一些前置初始化操作或者是對當前請求的一個預處理,也可以在這個方法中進行一些判斷來決定請求是否要繼續進行下去。該方法的返回值是布林值Boolean 型別的,當它返回為false 時,表示請求結束,後續的Interceptor 和Controller 都不會再執行;當返回值為true 時就會繼續呼叫下一個Interceptor 的preHandle 方法,如果已經是最後一個Interceptor 的時候就會是呼叫當前請求的Controller 方法。

     (2)postHandle 方法,顧名思義就是在當前請求進行處理之後,也就是Controller 方法呼叫之後執行,但是它會在DispatcherServlet 進行檢視返回渲染之前被呼叫,所以我們可以在這個方法中對Controller 處理之後的ModelAndView 物件進行操作。

     (3)afterCompletion法將在整個請求結束之後,也就是在DispatcherServlet 渲染了對應的檢視之後執行。這個方法的主要作用是用於進行資源清理工作的。

     2.過濾器的使用

     專案中使用:編寫實現介面的類+web.xml中配置

     過濾器只需要實現javax.servlet.filter,重寫doFilter(...)、init(...)和destroy(..)方法即可    

     實現doFilter方法,完成對請求或響應的過濾

     實現init方法,讀取過濾器的初始化引數

     destroy(),過濾器銷燬的時候做一些操作

     3.監聽器的使用

     專案中使用:編寫實現介面的類+springMVC.xml中配置

     監聽器介面主要有四類八種,能夠監聽包括request域,session域,application域的產生,銷燬和屬性的變化

    監聽物件的建立:

     (1)ServletContext:主要監聽servletContext的建立,需要實現ServeltContextListener介面;

     (2)ServletRequest:主要監聽request的建立,需要實現ServletRequestListener介面;

     (3)HttpSession:主要監聽session的建立,需要實現HttpSessionListener介面

     監聽屬性的改變:

     (1)ServletContext:主要監聽servletContext屬性的更改、新增、刪除,需要實現ServeltContextAttrbuteListener介面;

    (2)ServletRequest:主要監聽request屬性的更改、新增、刪除, 需要實現ServletRequestAttrbuteListener介面;                        (3)HttpSession:主要監聽session屬性的更改、新增、刪除,需要實現HttpSessionAttrbuteListener介面。

     監聽session的活化與鈍化:httpSessionActivationListener主要監聽了session的活化與鈍化。

     監聽session與物件的繫結:httpSessionBindingListener監聽了session與物件的繫結。

三、常見問題及解決

      攔截器、過濾器、監聽器的區別是什麼?

     1.從關注的點來說:過濾器攔截器作用域web請求,並對一些資訊做相應的更改;監聽器作用於系統級別的引數的監聽,一般不做更改。

     2.所依賴的支援來說:攔截器需要Spring的支援;過濾器、監聽器需要servlet的支援。

     3.應用場景的不同

     (1)攔截器:攔截未登入、審計日誌等;

     (2)過濾器:設定字元編碼、URL級別的許可權訪問控制、過濾敏感詞彙、壓縮響應資訊等;

     (3)監聽器:統計線上人數、清除過期session。

四、編碼實戰

       詳見視訊。

五、擴充套件思考

     1.攔截器、過濾器、監聽器的執行順序

       監聽器 > 過濾器 > 攔截器 > servlet執行 > 攔截器 > 過濾器 > 監聽器

     2.多個攔截器的執行順序(兩個)

     (1)當倆個攔截器都實現放行操作時,順序為preHandle 1,preHandle 2,postHandle 2,postHandle 1,afterCompletion 2,afterCompletion 1;

     (2)當第一個攔截器preHandle返回false,也就是對其進行攔截時,第二個攔截器是完全不執行的,第一個攔截器只執行preHandle部分;

     (3)當第一個攔截器preHandle返回true,第二個攔截器preHandle返回false,順序為preHandle 1,preHandle 2 ,afterCompletion 1。

      3.多個過濾器的執行順序

     web伺服器根據Filter在web.xml中的註冊順序,決定先呼叫哪個Filter,當第一個Filter的doFilter方法被呼叫時,web伺服器會建立一個代表Filter鏈的FilterChain物件傳遞給該方法,在doFilter方法中,開發人員如果呼叫了FilterChain物件的doFilter方法,則web伺服器會檢查FilterChain物件中是否還有filter,如果有,則呼叫第二個filter,如果沒有,則呼叫目標資源。

     4.多個監聽器的執行順序

     一個webServlet裡面若有多個監聽器的話,順序是按照載入的順序來載入和註冊的這些servlet監聽器的。

 六、參考文獻

https://blog.csdn.net/c_royi/article/details/80563131

http://www.r9it.com/20171127/filter-interceptor-lisener.html
https://blog.csdn.net/java_zhaoyanli/article/details/43406385
https://www.cnblogs.com/HigginCui/p/5772514.html

https://blog.csdn.net/fugushiba/article/details/79745398

七、更多討論

     1.怎樣使用自定義註解實現攔截器?

     首先需要定義一個自定義的註解

     @Target(ElementType.METHOD )

     @Retention(RetentionPolicy.RUNTIME)

     public @interface AccessRequired {

     }

     這裡的ElementType.METHOD 表示的是對方法有效

     RetentionPolicy.RUNTIME

     一般如果需要在執行時去動態獲取註解資訊,那隻能用 RUNTIME 註解

     然後在編寫自己的攔截器,web.xml檔案中也需要配置

     最後在需要攔截的方法上標上自定義註解,表示需要攔截這個方法。

     2.未登入或者非vip的話,可以試看10分鐘怎麼解決 ?

     將視訊分段,前十分鐘是一個請求,之後再次請求,攔截後邊這個請求

     3.攔截器與過濾器的區別 :

    (1)攔截器是基於java的反射機制的,而過濾器是基於函式回撥。

    (2)攔截器不依賴與servlet容器,過濾器依賴與servlet容器。

     (3)攔截器只能對action請求起作用,而過濾器則可以對幾乎所有的請求起作用。

     (4)攔截器可以訪問action上下文、值棧裡的物件,而過濾器不能訪問。

     (5)在action的生命週期中,攔截器可以多次被呼叫,而過濾器只能在容器初始化時被呼叫一次

八、視訊教程

https://v.qq.com/x/page/d0706lh79aa.html

快點加入我們吧:http://www.jnshu.com/login/1/23284132

 

PPT連結 視訊連結

 

 

 

 

更多內容,可以加入IT交流群565734203與大家一起討論交流

 

這裡是技能樹·IT修真院:http://www.jsnhu.com,初學者轉行到網際網路的聚集地