天天看點

Struts2架構學習之六:了解并使用攔截器

前言

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

從struts2的工作流程說起

首先請看截取自官方的一張圖:

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的某個狀态進行攔截操作,使用攔截器可以更友善處理業務邏輯。除了以上方式的開發攔截器外還有注解方式,不過注解方式的一個明顯缺點是不利于代碼的複用,而且注解的底層使用反射的方式完成的,是以使用注解開發,性能是一個值得考慮的問題。