攔截器,在AOP(Aspect-Oriented Programming)中用於在某個方法或字段被訪問以前,進行攔截而後在以前或以後加入某些操做。攔截是AOP的一種實現策略。web
在Webwork的中文文檔的解釋爲——攔截器是動態攔截Action調用的對象。它提供了一種機制可使開發者能夠定義在一個action執行的先後執行的代碼,也能夠在一個action執行前阻止其執行。同時也是提供了一種能夠提取action中可重用的部分的方式。apache
談到攔截器,還有一個詞你們應該知道——攔截器鏈(Interceptor Chain,在Struts 2中稱爲攔截器棧Interceptor Stack)。攔截器鏈就是將攔截器按必定的順序聯結成一條鏈。在訪問被攔截的方法或字段時,攔截器鏈中的攔截器就會按其以前定義的順序被調用。瀏覽器
大部分時候,攔截器方法都是經過代理的方式來調用的。Struts 2的攔截器實現相對簡單。當請求到達Struts 2的ServletDispatcher時,Struts 2會查找配置文件,並根據其配置實例化相對的攔截器對象,而後串成一個列表(list),最後一個一個地調用列表中的攔截器。以下圖:cookie
Struts 2已經爲您提供豐富多樣的,功能齊全的攔截器實現。你們能夠至struts2的jar包內的struts-default.xml查看關於默認的攔截器與攔截器鏈的配置。session
Struts2(XWork)提供的攔截器的功能說明:app
攔截器框架 |
名字jsp |
說明 |
Alias Interceptor |
alias |
在不一樣請求之間將請求參數在不一樣名字件轉換,請求內容不變 |
Chaining Interceptor |
chain |
讓前一個Action的屬性能夠被後一個Action訪問,如今和chain類型的result(<result type=」chain」>)結合使用。 |
Checkbox Interceptor |
checkbox |
添加了checkbox自動處理代碼,將沒有選中的checkbox的內容設定爲false,而html默認狀況下不提交沒有選中的checkbox。 |
Cookies Interceptor |
cookies |
使用配置的name,value來是指cookies |
Conversion Error Interceptor |
conversionError |
將錯誤從ActionContext中添加到Action的屬性字段中。 |
Create Session Interceptor |
createSession |
自動的建立HttpSession,用來爲須要使用到HttpSession的攔截器服務。 |
Debugging Interceptor |
debugging |
提供不一樣的調試用的頁面來展示內部的數據情況。 |
Execute and Wait Interceptor |
execAndWait |
在後臺執行Action,同時將用戶帶到一箇中間的等待頁面。 |
Exception Interceptor |
exception |
將異常定位到一個畫面 |
File Upload Interceptor |
fileUpload |
提供文件上傳功能 |
I18n Interceptor |
i18n |
記錄用戶選擇的locale |
Logger Interceptor |
logger |
輸出Action的名字 |
Message Store Interceptor |
store |
存儲或者訪問實現ValidationAware接口的Action類出現的消息,錯誤,字段錯誤等。 |
Model Driven Interceptor |
model-driven |
若是一個類實現了ModelDriven,將getModel獲得的結果放在Value Stack中。 |
Scoped Model Driven |
scoped-model-driven |
若是一個Action實現了ScopedModelDriven,則這個攔截器會從相應的Scope中取出model調用Action的setModel方法將其放入Action內部。 |
Parameters Interceptor |
params |
將請求中的參數設置到Action中去。 |
Prepare Interceptor |
prepare |
若是Acton實現了Preparable,則該攔截器調用Action類的prepare方法。 |
Scope Interceptor |
scope |
將Action狀態存入session和application的簡單方法。 |
Servlet Config Interceptor |
servletConfig |
提供訪問HttpServletRequest和HttpServletResponse的方法,以Map的方式訪問。 |
Static Parameters Interceptor |
staticParams |
從struts.xml文件中將<action>中的<param>中的內容設置到對應的Action中。 |
Roles Interceptor |
roles |
肯定用戶是否具備JAAS指定的Role,不然不予執行。 |
Timer Interceptor |
timer |
輸出Action執行的時間 |
Token Interceptor |
token |
經過Token來避免雙擊 |
Token Session Interceptor |
tokenSession |
和Token Interceptor同樣,不過雙擊的時候把請求的數據存儲在Session中 |
Validation Interceptor |
validation |
使用action-validation.xml文件中定義的內容校驗提交的數據。 |
Workflow Interceptor |
workflow |
調用Action的validate方法,一旦有錯誤返回,從新定位到INPUT畫面 |
Parameter Filter Interceptor |
N/A |
從參數列表中刪除沒必要要的參數 |
Profiling Interceptor |
profiling |
經過參數激活profile |
在struts.xml文件中定義攔截器,攔截器棧:
<package name="my" extends="struts-default" namespace="/manage"> <interceptors> <!-- 定義攔截器 --> <interceptor name="攔截器名" class="攔截器實現類"/> <!-- 定義攔截器棧 --> <interceptor-stack name="攔截器棧名"> <interceptor-ref name="攔截器一"/> <interceptor-ref name="攔截器二"/> </interceptor-stack> </interceptors> ...... </package> |
一旦定義了攔截器和攔截器棧後,就可使用這個攔截器或攔截器棧來攔截Action了。攔截器的攔截行爲將會在Action的exceute方法執行以前被執行。
<action name="userOpt" class="org.qiujy.web.struts2.action.UserAction"> <result name="success">/success.jsp</result> <result name="error">/error.jsp</result> <!-- 使用攔截器,通常配置在result以後, --> <!-- 引用系統默認的攔截器 --> <interceptor-ref name="defaultStack"/> <interceptor-ref name="攔截器名或攔截器棧名"/> </action> |
此處須要注意的是,若是爲Action指定了一個攔截器,則系統默認的攔截器棧將會失去做用。爲了繼續使用默認攔截器,因此上面配置文件中手動引入了默認攔截器。
做爲「框架(framework)」,可擴展性是不可或缺的。雖然,Struts 2爲咱們提供如此豐富的攔截器實現,可是這並不意味咱們失去建立自定義攔截器的能力,偏偏相反,在Struts 2自定義攔截器是至關容易的一件事。
全部的Struts 2的攔截器都直接或間接實現接口com.opensymphony.xwork2.interceptor.Interceptor。該接口提供了三個方法:
1) void init(); 在該攔截器被初始化以後,在該攔截器執行攔截以前,系統回調該方法。對於每一個攔截器而言,此方法只執行一次。
2) void destroy();該方法跟init()方法對應。在攔截器實例被銷燬以前,系統將回調該方法。
3) String intercept(ActionInvocation invocation) throws Exception; 該方法是用戶須要實現的攔截動做。該方法會返回一個字符串做爲邏輯視圖。
除此以外,繼承類com.opensymphony.xwork2.interceptor.AbstractInterceptor是更簡單的一種實現攔截器類的方式,由於此類提供了init()和destroy()方法的空實現,這樣咱們只須要實現intercept方法。
兩個步驟:
l 經過<interceptor …>元素來定義攔截器。
l 經過<interceptor-ref …>元素來使用攔截器。
使用自定義攔截器來完成用戶權限的控制:當瀏覽者須要請求執行某個操做時,應用須要先檢查瀏覽者是否登陸,以及是否有足夠的權限來執行該操做。
AuthorizationInterceptor.java
package org.qiujy.common;
import java.util.Map;
import com.opensymphony.xwork2.Action; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
/** * 權限檢查攔截器 * * @author qiujy * @version 1.0 */ public class AuthorizationInterceptor extends AbstractInterceptor {
/* * 攔截Action處理的攔截方法 * */ public String intercept(ActionInvocation invocation) throws Exception {
Map session = invocation.getInvocationContext().getSession(); String userName = (String) session.get("userName");
if (null != userName && userName.equals("test")) { System.out.println("攔截器:合法用戶登陸---"); return invocation.invoke(); } else { System.out.println("攔截器:用戶未登陸---"); return Action.LOGIN; } } } |
struts.xml:
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts> <package name="my" extends="struts-default">
<interceptors> <!-- 定義權限控制攔截器 --> <interceptor name="authority" class="org.qiujy.common.AuthorizationInterceptor"/> </interceptors>
<!-- 定義全局處理結果 --> <global-results> <!-- 邏輯名爲login的結果,映射到/login.jsp頁面 --> <result name="login">/login.jsp</result> </global-results>
<action name="listall" class="org.qiujy.web.struts2.action.UserAction" method="listAllUser"> <result name="success">/listall.jsp</result> <!-- 使用攔截器 --> <interceptor-ref name="defaultStack"/> <interceptor-ref name="authority"/> </action>
<action name="userOpt" class="org.qiujy.web.struts2.action.UserAction"> <result name="success">/success.jsp</result> </action> </package> </struts> |
其它頁面見源代碼。
在瀏覽器地址欄直接輸入http://localhost:8080/AuthorityInterceptorDemo/listall.action 來訪問,此動做配置了權限攔截器,全部被轉到登陸頁面。
登陸後:
再訪問http://localhost:8080/AuthorityInterceptorDemo/listall.action 這個連接:
若是爲了簡化struts.xml文件的配置,避免在每一個Action重複配置該攔截器,能夠將攔截器配置成了一個默認攔截器棧。以下:
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts> <package name="my" extends="struts-default">
<interceptors> <!-- 定義權限控制攔截器 --> <interceptor name="authority" class="org.qiujy.common.AuthorizationInterceptor" /> <!-- 定義一個包含權限控制的攔截器棧 --> <interceptor-stack name="mydefault"> <interceptor-ref name="defaultStack" /> <interceptor-ref name="authority" /> </interceptor-stack> </interceptors>
<!-- 定義默認攔截器 --> <default-interceptor-ref name="mydefault" />
<!-- 定義全局處理結果 --> <global-results> <!-- 邏輯名爲login的結果,映射到/login.jsp頁面 --> <result name="login">/login.jsp</result> </global-results>
<action name="listall" class="org.qiujy.web.struts2.action.UserAction" method="listAllUser"> <result name="success">/listall.jsp</result> </action> </package>
<package name="font" extends="struts-default"> <action name="userOpt" class="org.qiujy.web.struts2.action.UserAction"> <result name="success">/success.jsp</result> </action> </package> </struts> |
一旦在某個包下定義了默認攔截器棧,在該包下的全部action都會使用此攔截器棧。對於那些不想使用些攔截器棧的action,則應該將它放置在其它的包下。