這里是修真院后端小課堂,每篇分享文從
【背景介紹】【知識剖析】【常見問題】【解決方案】【編碼實戰】【擴展思考】【更多討論】【參考文獻】
八個方面深度解析后端知識/技能,本篇分享的是:
【 攔截器、過濾器、監聽器各有什么作用】
大家好,我是IT修真院西安分院第4期的JAVA學員,一枚正直純潔善良的JAVA程序員。今天給大家分享一下,攔截器、過濾器、監聽器各有什么作用
一、.背景介紹
1、攔截器
Interceptor是動態攔截Action調用的對象。它提供了一種機制可以使開發者可以定義在一個Action執行
的前后執行的代碼,也可以在一個Action執行前阻止其執行 。同時也提供了一種可以提取Action中可重用
的部分的方式。
2、過濾器
Filter是實現了javax.servlet.Filter接口的服務器端程序,主要的用途是過濾字符編碼,做一些業務邏輯
判斷,過濾器隨web應用啟動而啟動,只初始化一次,只有當web應用停止或重新部署才銷毀
3、 監聽器
Listener是實現了javax.servlet.ServletContextListener接口的服務器端程序,
它也是隨web應用的啟動而啟動,只初始化了一次,隨web應用的停止而銷毀。
主要作用是:做一些初始化的內容添加工作、設置一些基本的內容、比如一些參數或者
是一些固定的對象等等。
二、知識剖析
2.知識剖析
攔截器的實現方法:
主要通過兩種途徑,第一種是實現HandlerInterceptor接口,第二種是實現WebRequestInterceptor接口。</P>
攔截器的使用
項目中使用:編寫實現接口的類+springMVC.xml中配攔截器只需要實現HandlerInterceptor或者WebRequestInterceptor, 重寫相應的preHandle(...)、postHandle(...)和afterCompletion(...)方法即可</p>
(1)HandlerInterceptor 接口
在該接口中,定義了 3 個方法,分別為preHandle()、postHandle()和afterCompletion(),通過復寫這 3 個方法來對用戶的請求進行攔截處理
而且在 Spring 框架中,還提供了另外一個接口和一個抽象類,實現了對HandlerInterceptor接口的功能擴展,分別為:AsyncHandlerInterceptor和HandlerInterceptorAdapter.
在實際應用中,一般都是通過實現HandlerInterceptor接口或者繼承HandlerInterceptorAdapter抽象類
1)preHandle方法,該方法在請求處理之前進行調用。
SpringMVC 中的 Interceptor 是鏈式調用的,在一個請求中可以同時存在多個 Interceptor 。每個 Interceptor 的調用會依據它的聲明順序依次執行,而且最先執行的都是preHandle 方法,因此可以在這個方法中進行一些前置初始化操作或者是對當前請求做一個預處理,也可以進行一些判斷來決定請求是否要繼續進行下去。
當它返回為 false 時,表示請求結束,后續的 Interceptor 和 Controller 都不會再執行;
當返回值為 true 時,就會繼續調用下一個 Interceptor 的 preHandle 方法,如果已經是最后一個 Interceptor 的時候,就會調用當前請求的 Controller 中的方法。
2)postHandle方法在在當前所屬的 Interceptor 的 preHandle 方法的返回值為 true 的時候,才能被調用。
當前請求被處理之后,也就是在 Controller 中的方法調用之后執行,但是它會在 DispatcherServlet 進行視圖返回渲染之前被調用,所以可以在這個方法中對 Controller 處理之后的 ModelAndView 對象進行操作。
postHandle 方法被調用的方向跟 preHandle 是相反的,先聲明的 postHandle 方法反而會后執行。
3)afterCompletion方法,也是需要當前對應的 Interceptor 的 preHandle 方法的返回值為 true 時才會執行。因此,該方法將在整個請求結束之后,也就是在 DispatcherServlet 渲染了對應的視圖之后執行,這個方法的主要作用是用於進行資源清理的工作。
(2)WebRequestInterceptor 接口
在此接口中也定義了 3 個方法,同HandlerInterceptor接口完全相同,也需要復寫這 3 個方法來對用戶的請求進行攔截處理。而且這 3 個方法都傳遞了同一個參數 WebRequest。
它里面的方法定義跟 HttpServletRequest 類似,在WebRequestInterceptor中對 WebRequest 進行的所有操作都將同步到 HttpServletRequest 中,然后在當前請求中依次傳遞。
1)preHandle(WebRequest request)方法,該方法跟 HandlerInterceptor 中的 preHandle 不同,
主要區別在於該方法無返回值。因此不能通過返回值決定是否終止請求。其主要作用是進行資源的准備工作。
2)postHandle(WebRequest request, ModelMap model)方法,同樣也是在controller之后,
視圖返回被渲染之前被調用。該方法有兩個參數,WebRequest 對象是用於傳遞整個請求數據的,
比如在 preHandle 中准備的數據都可以通過 WebRequest 來傳遞和訪問;
3)afterCompletion(WebRequest request, Exception ex)方法,同樣是在視圖渲染之后調用, 主要用來進行資源的釋放。
過濾器
Servlet API中提供了一個Filter接口,開發web應用時,如果編寫的Java類實現了這個接口,則把這個java類稱之為過濾器Filter。通過Filter 技術,開發人員可以實現用戶在訪問某個目標資源之前,對訪問的請求和響應進行攔截。
Filter接口中有一個doFilter方法,當我們編寫好Filter,並配置對哪個web資源進行攔截后,WEB服務器每次在調用web資源的service方法之前,都會先調用一下filter的doFilter方法,因此,在該方法內編寫代碼可達到如下目的:
調用目標資源之前,讓一段代碼執行;
是否調用目標資源(即是否讓用戶訪問web資源);
調用目標資源之后,讓一段代碼執行。<br>
過濾器的使用
項目中使用:編寫實現接口的類+web.xml中配置
過濾器只需要實現javax.servlet.filter,重寫doFilter(...)、init(...)和destroy(..)方法即可
web服務器在調用doFilter方法時,會傳遞一個filterChain對象進來,
filterChain對象是filter接口中最重要的一個對 象,它也提供了一個doFilter方 ,開發人員可以根據需求決定是否調用此方法,調用該方法,
則web服務器就會調用web資源的service方 法,即web資源就會被訪問,否則web資源不會被訪問。</p>
過濾器中的方法
init: 程序啟動時,web服務器將創建Filter的實例對象,並調用其init方法,完成對象的初始化 功能;filter對象只會創建一次,init方法也只會執行一次。
doFilter:當訪問web服務器時對請求進行操作。
destroy:web容器調用destroy方法銷毀Filter。destroy方法在Filter的生命周期中僅執行一次。在destroy方法中,可以釋放過濾器使用的資源。
監聽器
監聽web應用,監聽許多信息的初始化,銷毀,增加,修改,刪除等 。
監聽器對象可以在事情發生前、發生后可以做一些必要的處理。
監聽器的分類
<p>1、ServletContext監聽</p>
<p>ServletContextListener:用於對Servlet整個上下文進行監聽(創建、銷毀)。</p>
<p>ServletContextAttributeListener:對Servlet上下文屬性的監聽(增刪改屬性)。
需要實現ServeltContextAttrbuteListener接口;</p>
<p>2、Session監聽</p>
<p>HttpSessionListener接口:對Session的整體狀態的監聽。</p>
<p>HttpSessionAttributeListener接口:對session的屬性監聽。
主要監聽session屬性的更改、添加、刪除,需要實現HttpSessionAttrbuteListener接口</p>
3、Request監聽
ServletRequestListener:用於對Request請求進行監聽(創建、銷毀)。
ServletRequestAttributeListener:對Request屬性的監聽(增刪改屬性)。
需要實現ServletRequestAttrbuteListener接口;
監聽器的使用
項目中使用:編寫實現接口的類+web.xml中配置
監聽器接口主要有四類八種,能夠監聽包括request域,session域,
application域的產生,銷毀和屬性的變化
監聽對象的創建:1.ServletContext:主要監聽servletContext的創建,
需要實現ServeltContextListener接口;
2.ServletRequest:主要監聽request的創建,
需要實現ServletRequestListener接口;3.HttpSession:主要監聽session的創建,
需要實現HttpSessionListener接口
三、常見問題
攔截器、過濾器、監聽器的區別是什么?
四、解決方案
1.從關注的點來說:過濾器攔截器作用域web請求,並對一些信息做相應的更改;監聽器作用於系統級別的參數的監聽,一般不做更改。
2.所依賴的支持來說:攔截器需要Spring的支持;過濾器、監聽器需要servlet的支持。
3.應用場景的不同
攔截器:攔截未登錄、審計日志等;
過濾器:設置字符編碼、URL級別的權限訪問控制、過濾敏感詞匯、壓縮響應信息等;
監聽器:統計在線人數、清除過期session
五、編碼實戰
六、擴展思考
1.攔截器、過濾器、監聽器的執行順序?
1.攔截器、過濾器、監聽器的執行順序
監聽器 > 過濾器 > 攔截器 > servlet執行 > 攔截器 > 過濾器 > 監聽器
七、參考文獻
https://www.cnblogs.com/qdhxhz/p/8468913.html
八、更多討論
Q1:(西安分院秦永輝)2.多個攔截器的執行順序(兩個)</p>
(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。
Q2:(西安分院郭靖).多個過濾器的執行順序
web服務器根據Filter在web.xml中的注冊順序,決定先調用哪個Filter,當第一個Filter的doFilter方法被調用時,web服務器會創建一個代表Filter鏈的FilterChain對象傳遞給該方法,在doFilter方法中,開發人員如果調用了FilterChain對象的doFilter方法,則web服務器會檢查FilterChain對象中是否還有filter,如果有,則調用第二個filter,如果沒有,則調用目標資源。
Q3: (西安分院秦永輝) 4.多個監聽器的執行順序
一個webServlet里面若有多個監聽器的話,順序是按照加載的順序來加載和注冊的這些servlet監聽器的。
這里是技能樹.IT修真院,成千上萬的師兄在這里找到了自己的學習路線,學習透明化,成長可見化,師兄1對1免費指導。快來與我一起學習吧~我的邀請碼:28769611,或者你可以直接點擊此鏈接:http://www.jnshu.com/login/1/28769611
今天的分享就到這里啦,歡迎大家點贊、轉發、留言、拍磚~
更多內容,可以加入IT交流群565734203與大家一起討論交流
這里是技能樹·IT修真院:https://www.jnshu.com,初學者轉行到互聯網的聚集地
