前言
攔截器是struts2架構的核心功能,了解并使用攔截器有助于更靈活使用struts2。攔截器與servlet中的過濾器有些類似卻又不盡相同。因為在struts2中攔截器更像一個可插拔的元件,圍繞action和result進行,可以在方法調用之前、之後使用。通過struts2的工作流程(後面還會看到一個請求在struts2中詳細的執行流程)可以發現調用一個action之前之後有許多的攔截器,這些攔截器都通過後才執行具體的action。對于每一個攔截器來說,可以直接傳回,進而終止餘下的攔截器。
從struts2的工作流程說起
首先請看截取自官方的一張圖:

從圖中可以看到,從一個具體的請求到action需要經過多個攔截器,action處理完畢之後,後續的攔截器會繼續執行,最終到浏覽器中。struts2的工作流程如下:
請求發送給strutsprepareandexecutefilter
strutsprepareandexecutefilter判斷該請求是否是一個struts2請求,如果是則進入第3步
如果是struts2請求,則把請求交給actionproxy,是action的代理類
actionproxy建立一個actioninvocation執行個體,并進行初始化
在執行具體的action之前,actionproxy會涉及相關攔截器的調用
action調用結束之後,會根據struts.xml檔案中action的result配置對象得到對應的傳回結果。調用execute方法之後,對傳回結果進行渲染
執行後面的攔截器
把結果傳回給浏覽器
從整個請求處理過程來看,攔截器是處理的關鍵。ok,通過以上請求處理過程,我們知道了一個攔截器在struts2中的工作方式。下面從編寫一個簡單的攔截開始,學習使用攔截器。
一個簡單的攔截器
主要有兩種方式:
實作interceptor接口
繼承abstractinterceptor抽象類
編寫自己的攔截器必須實作com.opensymphony.xwork2.interceptor.interceptor接口,該接口有三個方法:init()、destroy()、intercept()。init方法在攔截器執行個體建立之後,intercept方法之前調用,主要用于初始化攔截器所需要的資源;destroy方法在攔截器執行個體銷毀之前調用,用于銷毀init初始化配置設定的資源;intercept方法則是在action執行之前調用,可以通過invocation對象擷取action的狀态,進而根據狀态的不同進行需要的攔截操作。
下面以實作interceptor接口為例,編寫一個計算action執行execute方法的時間的攔截器。代碼如下:
在編寫一個action并在struts.xml配置檔案中進行配置,在浏覽器中進行測試就可以得到執行execute方法的具體時間了。在編寫攔截器類的時候需要注意:在攔截器中不應該有執行個體變量,因為攔截器是無狀态的,無狀态的解釋是如果攔截器有狀态,那麼在多線程同時通路攔截器執行個體的時候,攔截器的狀态是不可預知的。
至此,我們已經學會了如何編寫一個簡單的攔截器,下面介紹在攔截器中自帶的攔截器喲哪些。
struts2中自帶的攔截器
自帶的攔截器可以在struts-default.xml檔案中得到,主要有:
execandwait(該攔截器可以讓需要運作較長時間的action在背景運作,并向使用者顯示進度資訊)
exception(主要用于異常處理)
fileupload(用于檔案上傳)
i18n(國際化的支援)
logger(日志,記錄action的開始于結束日志)
modeldriven(支援模型驅動的攔截器)
validation(定義自己的驗證器)
開發安全驗證功能的攔截器
在日常開發中,進行登入驗證是很常見的。這裡開發的攔截器主要實作的功能是:如果使用者沒有登入則提示沒有登入的資訊,并傳回到登入頁面。如果使用者已經登入,則顯示資源。這裡主要介紹實際開發中攔截器的開發步驟。
步驟1:編寫基本頁面
登入頁面:
登入成功頁面:
資源頁面:
步驟二:編寫action
loginaction2.java:
步驟四:編寫攔截器
代碼如下:
步驟五:在struts.xml中進行配置
步驟六:在浏覽器中輸入http:localhost:8090/struts2/login2!input進行測試。
至此,一個安全驗證的攔截器就開發完畢。
攔截器小結
從開發過程可以看待,攔截器的作用是action的某個狀态進行攔截操作,使用攔截器可以更友善處理業務邏輯。除了以上方式的開發攔截器外還有注解方式,不過注解方式的一個明顯缺點是不利于代碼的複用,而且注解的底層使用反射的方式完成的,是以使用注解開發,性能是一個值得考慮的問題。