過濾器、監聽器、攔截器
- 項目啟動時,先啟動監聽器,再啟動過濾器
三者間關系
1、攔截器是基於Java的反射機制的,而過濾器是基於函數回調
2、過濾器依賴與servlet容器,而攔截器不依賴與servlet容器
3、攔截器只能對action請求起作用,而過濾器則可以對幾乎所有的請求起作用
4、攔截器可以訪問action上下文、值棧里的對象,而過濾器不能
5、在action的生命周期中,攔截器可以多次被調用,而過濾器只能在容器初始化時被調用一次
6.執行順序:過濾前 - 攔截前 - Action處理 - 攔截后 -過濾后。個人認為過濾是一個橫向的過程,首先把客戶端提交的內容進行過濾(例如未登錄用戶不能訪問內部頁面的處理);過濾通過后,攔截器將檢查用戶提交數據的驗證,做一些前期的數據處理,接着把處理后的數據發給對應的Action;Action處理完成返回后,攔截器還可以做其他過程,再向上返回到過濾器的后續操作。
-
過濾器(Filter):當你有一堆東西的時候,你只希望選擇符合你要求的某一些東西。定義這些要求的工具,就是過濾器。
-
攔截器(Interceptor):在一個流程正在進行的時候,你希望干預它的進展,甚至終止它進行,這是攔截器做的事情。
-
監聽器(Listener):當一個事件發生的時候,你希望獲得這個事件發生的詳細信息,而並不想干預這個事件本身的進程,這就要用到監聽器。
一、過濾器(javax.servlet.Filter)
-
實現了javax.servlet.Filter接口的服務器端程序,主要的用途是
過濾字符編碼
、做一些業務邏輯判斷
等。其工作原理是,只要你在web.xml文件配置好要攔截的客戶端請求,它都會幫你攔截到請求,此時你就可以對請求或響應(Request、Response)統一設置編碼,簡化操作;同時還可以進行邏輯判斷,如用戶是否已經登錄
、有沒有權限訪問該頁面
等等工作,它是隨你的web應用啟動而啟動
的,只初始化一次,以后就可以攔截相關的請求
,只有當你的web應用停止或重新部署的時候才能銷毀
。 -
有三個方法
-
void init(FilterConfig filterConfig) 用於完成過濾器的初始化
-
void destroy() 用於過濾器銷毀前,完成某些資源的回收
-
void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) 實現過濾功能,該方法對每個請求增加額外的處理
-
作用范圍:所有請求
-
應用:請求編碼轉換、敏感詞匯過濾、請求日志記錄
二、監聽器(javax.servlet.ServletContectListener)
-
Servlet的監聽器Listener,它是實現了javax.servlet.ServletContextListener接口的服務器端程序,它也是隨web應用的啟動而啟動,只初始化一次,隨web應用的停止而銷毀。主要作用是:做一些初始化的內容添加工作、設置一些基本的內容、比如一些參數或者是一些固定的對象等等。
-
定義了兩種方法
-
void contextInitialized(ServletContextEvent sce) 監聽器的初始化
-
void contextDestroyed(ServletContextEvent sce) 監聽器銷毀
-
監聽范圍:request、session、application
-
應用:監聽在線人數、最大登錄人數
三、攔截器(AOP)
- AOP思想的實現,自定義攔截器需要實現以下方法
-
preHandle方法:進入Handler方法之前執行。可以用於身份認證、身份授權。比如如果認證沒有通過表示用戶沒有登陸,需要此方法攔截不再往下執行(return false),否則就放行(return true)。
-
postHandle方法:進入Handler方法之后,返回ModelAndView之前執行。可以看到該方法中有個modelAndView的形參。應用場景:從modelAndView出發:將公用的模型數據(比如菜單導航之類的)在這里傳到視圖,也可以在這里同一指定視圖。
-
afterCompletion方法:執行Handler完成之后執行。應用場景:統一異常處理,統一日志處理等。在springmvc中,攔截器是針對具體的HandlerMapping進行配置的,也就是說如果在某個HandlerMapping中配置攔截,經過該 HandlerMapping映射成功的handler最終使用該攔截器
- 應用:全局日志、登錄時間