攔截器

攔截器

攔截器(Interceptor),主要完成請求參數的解析、將頁面表單參數賦給值棧中相應屬性、執行功能檢驗、程序異常調試等工作。

原理


大部分時候,攔截器方法都是通過代理的方式來調用的。Struts2的攔截器實現相對簡單。當請求到達Struts2的ServletDispatcher時,Struts2會查找配置文件,並根據其配置實例化相對的攔截器對象,然後串成一個列表(list),最後一個一個地調用列表中的攔截器。Struts2攔截器是可插拔的,攔截器是AOP的一種實現。Struts2攔截器棧就是將攔截器按一定的順序聯結成一條鏈。在訪問被攔截的方法或欄位時,Struts2攔截器鏈中的攔截器就會按其之前定義的順序被調用。

定義


自定義一個攔截器需要三步:
1.自定義一個實現Interceptor介面(或者繼承自AbstractInterceptor)的類。
2.在struts.xml中註冊上一步中定義的攔截器。
3.在需要使用的Action中引用上述定義的攔截器,為了方便也可將攔截器定義為默認的攔截器,這樣在不加特殊聲明的情況下所有的Action都被這個攔截器攔截。

區別


過濾器可以簡單理解為“取你所想取”,忽視掉那些你不想要的東西;攔截器可以簡單理解為“拒你所想拒”,關心你想要拒絕掉哪些東西,比如一個BBS論壇上攔截掉敏感辭彙。
1.攔截器是基於java反射機制的,而過濾器是基於函數回調的。
2.過濾器依賴於servlet容器,而攔截器不依賴於servlet容器。
3.攔截器只對action起作用,而過濾器幾乎可以對所有請求起作用。
4.攔截器可以訪問action上下文、值棧里的對象,而過濾器不能。
5.在action的生命周期里,攔截器可以多起調用,而過濾器只能在容器初始化時調用一次。

簡介


攔截器(Interceptor)是Struts2框架的核心功能之一,Struts2是一個基於MVC設計模式的開源框架,主要完成請求參數的解析、將頁面表單參數賦給值棧中相應屬性、執行功能檢驗、程序異常調試等工作。Struts2攔截器是一種可插拔策略,實現了面向切面的組件開發,當需要擴展功能時,只需要提供對應攔截器,並將它配置在Struts2容器中即可,如果不需要該功能時,也只需要在配置文件取消該攔截器的設置,整個過程不需要用戶添加額外的代碼。攔截器中更為重要的概念即攔截器棧(InterceptorStack),攔截器棧就是Struts2中的攔截器按一定的順序組成的一個線性鏈,頁面發出請求,訪問Action對象或方法時,棧中被設置好的攔截器就會根據堆棧的原理順序的被調用。

默認攔截器


過濾器調度程序必須做的事情有很多,而沒有駐留在過濾器調度程序內部的代碼往往會被模塊化成一系列攔截器。攔截器可以通過編輯Struts配置文件而被插入或拔出。表格列出了Struts的默認攔截器。括弧里部分是在配置文件里註冊該攔截器時用的名字,在使用一個攔截器之前必須先在配置文件里註冊它,例如,Alias攔截器的註冊名是alias。

工作原理


Struts2中將各個功能對應的攔截器分開定義,每個攔截器完成單個功能,如果需要對Action運用某個功能就引用對應的攔截器。在實際開發中,經常需要在Action執行前同時執行多個攔截動作,如:用戶登錄檢查、登錄日誌記錄以及許可權檢查等,這時,可以把多個攔截器組成一個攔截器棧。所謂的攔截器棧是指對應各個功能的攔截器按照一定的順序排列形成的鏈,在使用時,可以將棧內的多個攔截器當成一個整體來引用。當攔截器棧被附加到一個Action上時,在執行Action之前必須先執行攔截器棧中的每一個攔截器。通常情況下,攔截器都是以代理方式調用的。
Struts2攔截器在Action執行前後進行攔截,圍繞著Action的執行而執行,比如實現日誌管理攔截器和安全功能的攔截器,在系統的Action關聯了攔截器,添加到Action執行過程中以後,系統的整個執行流程就變為:記錄日誌、執行安全檢測、執行Action、執行安全檢測、記錄日誌,在執行的過程中,每一個攔截器類的攔截方法決定是傳遞請求,還是終止請求。

許可權控制


在實際的Web應用軟體項目中,與項目的業務邏輯相關的通用功能需要開發人員自定義攔截器實現。比如Web應用軟體都要涉及到許可權控制這部分,當用戶訪問系統的受保護資源時,需要先檢查用戶是否已經登錄,以及是否有許可權訪問,可以由攔截器截獲用戶請求,判斷用戶是否已經登錄。
自定義攔截器
如果需要自定義攔截器類,該類就需要實現Interceptor介面。這個介面提供了攔截器的生命周期方法:(1)init()方法在攔截器被創建后調用,對系統相關資源進行必要的初始化工作。(2)destroy()方法在攔截器對象被銷毀之前調用,用來釋放和攔截器相關的資源。(3)intercept(ActionInvocationinvocation)方法是攔截器的核心方法,用來實現具體的攔截操作,可以通過ActionInvocation參數的invoke()方法,將控制權轉給下一個攔截器或者控制器Action。如果需要自定義攔截器類,只需要實現Interceptor介面的三個方法即可。然而在實際開發過程中,更常用的一種方式是繼承抽象攔截器類AbstractIntercepter,它實現了Interceptor介面,因此可以直接繼承該抽象類,簡化代碼的編寫。
實現許可權控制攔截器
判斷用戶是否登錄,可以跟蹤用戶的會話對象session來完成,利用ActionContext對象就可以可訪問到session中的屬性,攔截器執行攔截的intercepte方法的invocation參數可以得到ActionContext對象,通過ActionInvocation參數取得用戶的session實例的引用,從而判斷是否需要轉入登錄頁面。
配置許可權控制攔截器
如果要使用許可權控制攔截器,還要在項目的配置文件struts.xml中定義該攔截器。由於Struts2中很多核心功能都是由系統默認的defaultStack中的攔截器實現的,所以開發人員自定義的攔截器需要引用系統默認的defaultStack,這樣Web應用才可以使用Struts2框架提供的眾多功能。