? 攔截器的類已經定義在特殊的配置文件中,這個配置文件的名字就叫做struts-default.xml,如果你繼承了struts-default默認的包名,那你就可以使用這些攔截器了,否則你必須在你自己的包中定義攔截器在<interceptors>中進行定義。

下面是Struts2中的內置攔截器介紹
Interceptor Name Description
Alias Interceptor alias 在不同的請求之間將參數在不同的名字間轉換,請求內容不變.
Chaining Interceptor chain 讓前面一個Action的屬性可以被后一個Action訪問
Checkbox Interceptor checkbox Adds automatic checkbox handling code that detect an unchecked checkbox and add it as a parameter with a default (usually 'false') value. Uses a specially named hidden field to detect unsubmitted checkboxes. The default unchecked value is overridable for non-boolean value'd checkboxes.
Cookie Interceptor cookie 使用配置的name、value來設置cookies
Conversion Error Interceptor conversionError 將錯誤從ActionContext中添加到Action的屬性字段中
Create Session Interceptor createSession 自動地創建HttpSession,用來為需要使用到HttpSession的攔截器服務
DebuggingInterceptor 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得到的結果放在ValueStack中
Scoped Model Driven Interceptor scoped-model-driven 如果一個Action實現了ScopedModelDriven,則這個攔截器會從相應的Scope中取出model,調用Action的setModel方法將其放入Action內部
Parameters Interceptor params 將請求中的參數設置到Action中去
Prepare Interceptor prepare 如果Action實現了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 Interceptory一樣,不過雙擊的時候把請求的數據存儲在Session中
Validation Interceptor validation 使用action-validation.xml文件中定義的內容校驗提交的數據
Workflow Interceptor workflow 調用Action的validate的方法,一旦有錯返回,重新定位到INPUT頁面
Parameter Filter Interceptor N/A 從參數列表中刪除不必要的參數
Profiling Interceptor profiling 通過參數激活profile



? 每一個攔截器都可以配置參數,有兩種方式配置參數,一是針對每一個攔截器定義參數,二是針對一個攔截器堆棧統一定義所有的參數,例如:
<interceptor-ref?name="validation">?
<param?name="excludeMethods">myValidationExcudeMethod</param>?
</interceptor-ref>?
<interceptor-ref?name="workflow">?<param?name="excludeMethods">myWorkflowExcludeMethod</param>?</interceptor-ref>?




或者
<interceptor-ref?name="defaultStack">?<param?name="validation.excludeMethods">myValidationExcludeMethod</param>?<param?name="workflow.excludeMethods">myWorkflowExcludeMethod</param>?</interceptor-ref>?



每一個攔截器都有兩個默認的參數:
excludeMethods - 過濾掉不使用攔截器的方法和
includeMethods – 使用攔截器的方法。

需要說明的幾點:
1 攔截器執行的順序按照定義的順序執行,例如:

<interceptor-stack?name="xaStack">?<interceptor-ref?name="thisWillRunFirstInterceptor"/>?<interceptor-ref?name="thisWillRunNextInterceptor"/>?<interceptor-ref?name="followedByThisInterceptor"/>?<interceptor-ref?name="thisWillRunLastInterceptor"/>?</interceptor-stack>?



的執行順序為:

thisWillRunFirstInterceptor thisWillRunNextInterceptor followedByThisInterceptor thisWillRunLastInterceptor MyAction1 MyAction2 (chain) MyPreResultListener MyResult (result) thisWillRunLastInterceptor followedByThisInterceptor thisWillRunNextInterceptor thisWillRunFirstInterceptor



2 使用默認攔截器配置每個Action都需要的攔截器堆棧,例如:


<action?name="login"?class="tutorial.Login">?<interceptor-ref?name="timer"/>?<interceptor-ref?name="logger"/>?<interceptor-ref?name="default-stack"/>?<result?name="input">login.jsp</result>?<result?type="redirect-action">/secure/home</result>?</action>?


可以按照如下的方式定義:


<interceptors> <interceptor-stack name="myStack"> <interceptor-ref name="timer"/> <interceptor-ref name="logger"/> <interceptor-ref name="default-stack"/> </interceptor-stack> </interceptors> <default-interceptor-ref name="myStack"/> <action name="login" class="tutorial.Login"> <result name="input">login.jsp</result> <result type="redirect-action">/secure/home</result> </action>


自定義攔截器

??? 作為“框架(framework)”,可擴展性是不可或缺的,因為世上沒有放之四海而皆準的東西。雖然,Struts 2為我們提供如此豐富的攔截器實現,但是這并不意味我們失去創建自定義攔截器的能力,恰恰相反,在Struts 2自定義攔截器是相當容易的一件事。


大家在開始著手創建自定義攔截器前,切記以下原則:
攔截器必須是無狀態的,不要使用在API提供的ActionInvocation之外的任何東西。
??? 要求攔截器是無狀態的原因是Struts 2不能保證為每一個請求或者action創建一個實例,所以如果攔截器帶有狀態,會引發并發問題。
??? 所有的Struts 2的攔截器都直接或間接實現接口com.opensymphony.xwork2.interceptor.Interceptor。除此之外,大家可能更喜歡繼承類com.opensymphony.xwork2.interceptor.AbstractInterceptor。
以下例子演示通過繼承AbstractInterceptor,實現授權攔截器。
首先,創建授權攔截器類tutorial.AuthorizationInterceptor,代碼如下:?
package?tutorial;?

import?java.util.Map;?

import?com.opensymphony.xwork2.Action;?
import?com.opensymphony.xwork2.ActionInvocation;?
import?com.opensymphony.xwork2.interceptor.AbstractInterceptor;?

public?class?AuthorizationInterceptor?extends?AbstractInterceptor?{?

????@Override?
?????
public?String?intercept(ActionInvocation?ai)?throws?Exception?{?
????????Map?session?
=?ai.getInvocationContext().getSession();?
????????String?role?
=?(String)?session.get(?"?ROLE?"?);?
?????????
if?(?null?!=?role)?{?
????????????Object?o?
=?ai.getAction();?
?????????????
if?(o?instanceof?RoleAware)?{?
????????????????RoleAware?action?
=?(RoleAware)?o;?
????????????????action.setRole(role);?
????????????}
?
?????????????
return?ai.invoke();?
????????}
?else?{?
?????????????
return?Action.LOGIN;?
????????}
????????
????}
?

}
?
??

?? 以上代碼相當簡單,我們通過檢查session是否存在鍵為“ROLE”的字符串,判斷用戶是否登陸。如果用戶已經登陸,將角色放到Action中,調用Action;否則,攔截直接返回Action.LOGIN字段。為了方便將角色放入Action,我定義了接口tutorial.RoleAware,代碼如下:?
package?tutorial;?

public?interface?RoleAware?{?
?????
void?setRole(String?role);?
}
?



?? 接著,創建Action類tutorial.AuthorizatedAccess模擬訪問受限資源,它作用就是通過實現RoleAware獲取角色,并將其顯示到ShowUser.jsp中,代碼如下:?
package?tutorial;?

import?com.opensymphony.xwork2.ActionSupport;?

public?class?AuthorizatedAccess?extends?ActionSupport?implements?RoleAware?{?
?????
private?String?role;?
????
?????
public?void?setRole(String?role)?{?
?????????
this?.role?=?role;?
????}
?
????
?????
public?String?getRole()?{?
?????????
return?role;?
????}
?

????@Override?
?????
public?String?execute()?{?
?????????
return?SUCCESS;?
????}
?
}
?



?? 以下是ShowUser.jsp的代碼:?
<%?@?page??contentType?=?"?text/html;?charset=UTF-8?"?%>?
<%?@taglib?prefix?=?"?s?"?uri?=?"?/struts-tags?"?%>?
<?html?>?
<?head?>?
????
<?title?>?Authorizated?User?</?title?>?
</?head?>?
<?body?>?
????
<?h1?>?Your?role?is:?<?s:property?value?="role"?/></?h1?>?
</?body?>?
</?html?>?


??? 然后,創建tutorial.Roles初始化角色列表,代碼如下:?
package?tutorial;?

import?java.util.Hashtable;?
import?java.util.Map;?


public?class?Roles?{?
?????
public?Map?<?String,?String?>?getRoles()?{?
????????Map?
<?String,?String?>?roles?=?new?Hashtable?<?String,?String?>?(?2?);?
????????roles.put(?
"?EMPLOYEE?"?,?"?Employee?"?);?
????????roles.put(?
"?MANAGER?"?,?"?Manager?"?);?
?????????
return?roles;?
????}
?
}
?


???? 接下來,新建Login.jsp實例化tutorial.Roles,并將其roles屬性賦予<s:radio>標志,代碼如下:?
<%?@?page??contentType?=?"?text/html;?charset=UTF-8?"?%>?
<%?@taglib?prefix?=?"?s?"?uri?=?"?/struts-tags?"?%>?
<?html?>?
<?head?>?
????
<?title?>?Login?</?title?>?
</?head?>?
<?body?>?
????
<?h1?>?Login?</?h1?>?
????Please?select?a?role?below:?
????
<?s:bean?id?="roles"?name?="tutorial.Roles"?/>?
????
<?s:form?action?="Login"?>?
????????
<?s:radio?list?="#roles.roles"?value?="'EMPLOYEE'"?name?="role"?label?="Role"?/>?
????????
<?s:submit?/>?
????
</?s:form?>?
</?body?>?
</?html?>?


??? 創建Action類tutorial.Login將role放到session中,并轉到Action類tutorial.AuthorizatedAccess,代碼如下:?
package?tutorial;?

import?java.util.Map;?

import?org.apache.struts2.interceptor.SessionAware;?

import?com.opensymphony.xwork2.ActionSupport;?

public?class?Login?extends?ActionSupport?implements?SessionAware?{?
?????
private?String?role;????
?????
private?Map?session;?

?????
public?String?getRole()?{?
?????????
return?role;?
????}
?

?????
public?void?setRole(String?role)?{?
?????????
this?.role?=?role;?
????}
?
????
?????
public?void?setSession(Map?session)?{?
?????????
this?.session?=?session;?
????}
?

????@Override?
?????
public?String?execute()?{?
????????session.put(?
"?ROLE?"?,?role);?
?????????
return?SUCCESS;?
????}
????
}
?

???
??? 最后,配置struts.xml文件,內容如下:
<!?DOCTYPE?struts?PUBLIC?
????????"-//Apache?Software?Foundation//DTD?Struts?Configuration?2.0//EN"?
????????"http://struts.apache.org/dtds/struts-2.0.dtd"?
>?
<?struts?>?
????
<?include?file?="struts-default.xml"?/>????
????
<?package?name?="InterceptorDemo"?extends?="struts-default"?>?
????????
<?interceptors?>?
????????????
<?interceptor?name?="auth"?class?="tutorial.AuthorizationInterceptor"?/>?
????????
</?interceptors?>?
????????
<?action?name?="Timer"?class?="tutorial.TimerInterceptorAction"?>?
????????????
<?interceptor-ref?name?="timer"?/>?
????????????
<?result?>?/Timer.jsp?</?result?>?
????????
</?action?>?
????????
<?action?name?="Login"?class?="tutorial.Login"?>?
????????????
<?result?type?="chain"?>?AuthorizatedAccess?</?result?>?
????????
</?action?>?
????????
<?action?name?="AuthorizatedAccess"?class?="tutorial.AuthorizatedAccess"?>?
????????????
<?interceptor-ref?name?="auth"?/>?
????????????
<?result?name?="login"?>?/Login.jsp?</?result?>?
????????????
<?result?name?="success"?>?/ShowRole.jsp?</?result?>?
????????
</?action?>?
????
</?package?>?
</?struts?>?