? 攔截器的類(lèi)已經(jīng)定義在特殊的配置文件中,這個(gè)配置文件的名字就叫做struts-default.xml,如果你繼承了struts-default默認(rèn)的包名,那你就可以使用這些攔截器了,否則你必須在你自己的包中定義攔截器在<interceptors>中進(jìn)行定義。
下面是Struts2中的內(nèi)置攔截器介紹
Interceptor Name Description
Alias Interceptor alias 在不同的請(qǐng)求之間將參數(shù)在不同的名字間轉(zhuǎn)換,請(qǐng)求內(nèi)容不變.
Chaining Interceptor chain 讓前面一個(gè)Action的屬性可以被后一個(gè)Action訪問(wèn)
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來(lái)設(shè)置cookies
Conversion Error Interceptor conversionError 將錯(cuò)誤從ActionContext中添加到Action的屬性字段中
Create Session Interceptor createSession 自動(dòng)地創(chuàng)建HttpSession,用來(lái)為需要使用到HttpSession的攔截器服務(wù)
DebuggingInterceptor debugging 提供不同的調(diào)試用的頁(yè)面來(lái)展示內(nèi)部的數(shù)據(jù)狀況
Execute and Wait Interceptor execAndWait 在后臺(tái)執(zhí)行Action,同時(shí)將用戶(hù)帶到一個(gè)中間的等待頁(yè)面
Exception Interceptor exception 將異常定位到一個(gè)頁(yè)面
File Upload Interceptor fileUpload 提供文件上傳功能
I18n Interceptor i18n 記錄用戶(hù)選擇的locale
Logger Interceptor logger 輸出Action的名字
Message Store Interceptor store 存儲(chǔ)或者訪問(wèn)實(shí)現(xiàn)ValidationAware接口的Action類(lèi)出現(xiàn)的消息、錯(cuò)誤、字段錯(cuò)誤等。
Model Driven Interceptor model-driven 如果一個(gè)類(lèi)實(shí)現(xiàn)了ModelDriven,將getModel得到的結(jié)果放在ValueStack中
Scoped Model Driven Interceptor scoped-model-driven 如果一個(gè)Action實(shí)現(xiàn)了ScopedModelDriven,則這個(gè)攔截器會(huì)從相應(yīng)的Scope中取出model,調(diào)用Action的setModel方法將其放入Action內(nèi)部
Parameters Interceptor params 將請(qǐng)求中的參數(shù)設(shè)置到Action中去
Prepare Interceptor prepare 如果Action實(shí)現(xiàn)了Preparable,則該攔截器調(diào)用Action類(lèi)的prepare方法
Scope Interceptor scope 將Action狀態(tài)存入Session和Application的簡(jiǎn)單方法
Servlet Config Interceptor servletConfig 提供訪問(wèn)HttpServletRequest和HttpServletResponse的方法,以Map的方式訪問(wèn)
Static Parameters Interceptor staticParams 從struts.xml文件中將<action>中的<param>下的內(nèi)容設(shè)置到對(duì)應(yīng)的Action中
Roles Interceptor roles 確定用戶(hù)是否具有JAAS指定的Role,否則不予執(zhí)行
Timer Interceptor timer 輸出Action執(zhí)行的時(shí)間
Token Interceptor token 通過(guò)Token來(lái)避免雙擊
Token Session Interceptor tokenSession 和Token Interceptory一樣,不過(guò)雙擊的時(shí)候把請(qǐng)求的數(shù)據(jù)存儲(chǔ)在Session中
Validation Interceptor validation 使用action-validation.xml文件中定義的內(nèi)容校驗(yàn)提交的數(shù)據(jù)
Workflow Interceptor workflow 調(diào)用Action的validate的方法,一旦有錯(cuò)返回,重新定位到INPUT頁(yè)面
Parameter Filter Interceptor N/A 從參數(shù)列表中刪除不必要的參數(shù)
Profiling Interceptor profiling 通過(guò)參數(shù)激活profile
? 每一個(gè)攔截器都可以配置參數(shù),有兩種方式配置參數(shù),一是針對(duì)每一個(gè)攔截器定義參數(shù),二是針對(duì)一個(gè)攔截器堆棧統(tǒng)一定義所有的參數(shù),例如:
<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>?
每一個(gè)攔截器都有兩個(gè)默認(rèn)的參數(shù):
excludeMethods - 過(guò)濾掉不使用攔截器的方法和
includeMethods – 使用攔截器的方法。
需要說(shuō)明的幾點(diǎn):
1 攔截器執(zhí)行的順序按照定義的順序執(zhí)行,例如:
<interceptor-stack?name="xaStack">?<interceptor-ref?name="thisWillRunFirstInterceptor"/>?<interceptor-ref?name="thisWillRunNextInterceptor"/>?<interceptor-ref?name="followedByThisInterceptor"/>?<interceptor-ref?name="thisWillRunLastInterceptor"/>?</interceptor-stack>?
的執(zhí)行順序?yàn)椋?
thisWillRunFirstInterceptor thisWillRunNextInterceptor followedByThisInterceptor thisWillRunLastInterceptor MyAction1 MyAction2 (chain) MyPreResultListener MyResult (result) thisWillRunLastInterceptor followedByThisInterceptor thisWillRunNextInterceptor thisWillRunFirstInterceptor
2 使用默認(rèn)攔截器配置每個(gè)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)”,可擴(kuò)展性是不可或缺的,因?yàn)槭郎蠜](méi)有放之四海而皆準(zhǔn)的東西。雖然,Struts 2為我們提供如此豐富的攔截器實(shí)現(xiàn),但是這并不意味我們失去創(chuàng)建自定義攔截器的能力,恰恰相反,在Struts 2自定義攔截器是相當(dāng)容易的一件事。
大家在開(kāi)始著手創(chuàng)建自定義攔截器前,切記以下原則:
攔截器必須是無(wú)狀態(tài)的,不要使用在API提供的ActionInvocation之外的任何東西。
??? 要求攔截器是無(wú)狀態(tài)的原因是Struts 2不能保證為每一個(gè)請(qǐng)求或者action創(chuàng)建一個(gè)實(shí)例,所以如果攔截器帶有狀態(tài),會(huì)引發(fā)并發(fā)問(wèn)題。
??? 所有的Struts 2的攔截器都直接或間接實(shí)現(xiàn)接口com.opensymphony.xwork2.interceptor.Interceptor。除此之外,大家可能更喜歡繼承類(lèi)com.opensymphony.xwork2.interceptor.AbstractInterceptor。
以下例子演示通過(guò)繼承AbstractInterceptor,實(shí)現(xiàn)授權(quán)攔截器。
首先,創(chuàng)建授權(quán)攔截器類(lèi)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;?
????????}????????
????}?

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


public?interface?RoleAware?
{?
?????void?setRole(String?role);?
}?
?? 接著,創(chuàng)建Action類(lèi)tutorial.AuthorizatedAccess模擬訪問(wèn)受限資源,它作用就是通過(guò)實(shí)現(xiàn)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?>?
??? 然后,創(chuàng)建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;?
????}?
}?
???? 接下來(lái),新建Login.jsp實(shí)例化tutorial.Roles,并將其roles屬性賦予<s:radio>標(biāo)志,代碼如下:?

<%
?@?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?>?
??? 創(chuàng)建Action類(lèi)tutorial.Login將role放到session中,并轉(zhuǎn)到Action類(lèi)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文件,內(nèi)容如下:
<!?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?>?
下面是Struts2中的內(nèi)置攔截器介紹
Interceptor Name Description
Alias Interceptor alias 在不同的請(qǐng)求之間將參數(shù)在不同的名字間轉(zhuǎn)換,請(qǐng)求內(nèi)容不變.
Chaining Interceptor chain 讓前面一個(gè)Action的屬性可以被后一個(gè)Action訪問(wèn)
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來(lái)設(shè)置cookies
Conversion Error Interceptor conversionError 將錯(cuò)誤從ActionContext中添加到Action的屬性字段中
Create Session Interceptor createSession 自動(dòng)地創(chuàng)建HttpSession,用來(lái)為需要使用到HttpSession的攔截器服務(wù)
DebuggingInterceptor debugging 提供不同的調(diào)試用的頁(yè)面來(lái)展示內(nèi)部的數(shù)據(jù)狀況
Execute and Wait Interceptor execAndWait 在后臺(tái)執(zhí)行Action,同時(shí)將用戶(hù)帶到一個(gè)中間的等待頁(yè)面
Exception Interceptor exception 將異常定位到一個(gè)頁(yè)面
File Upload Interceptor fileUpload 提供文件上傳功能
I18n Interceptor i18n 記錄用戶(hù)選擇的locale
Logger Interceptor logger 輸出Action的名字
Message Store Interceptor store 存儲(chǔ)或者訪問(wèn)實(shí)現(xiàn)ValidationAware接口的Action類(lèi)出現(xiàn)的消息、錯(cuò)誤、字段錯(cuò)誤等。
Model Driven Interceptor model-driven 如果一個(gè)類(lèi)實(shí)現(xiàn)了ModelDriven,將getModel得到的結(jié)果放在ValueStack中
Scoped Model Driven Interceptor scoped-model-driven 如果一個(gè)Action實(shí)現(xiàn)了ScopedModelDriven,則這個(gè)攔截器會(huì)從相應(yīng)的Scope中取出model,調(diào)用Action的setModel方法將其放入Action內(nèi)部
Parameters Interceptor params 將請(qǐng)求中的參數(shù)設(shè)置到Action中去
Prepare Interceptor prepare 如果Action實(shí)現(xiàn)了Preparable,則該攔截器調(diào)用Action類(lèi)的prepare方法
Scope Interceptor scope 將Action狀態(tài)存入Session和Application的簡(jiǎn)單方法
Servlet Config Interceptor servletConfig 提供訪問(wèn)HttpServletRequest和HttpServletResponse的方法,以Map的方式訪問(wèn)
Static Parameters Interceptor staticParams 從struts.xml文件中將<action>中的<param>下的內(nèi)容設(shè)置到對(duì)應(yīng)的Action中
Roles Interceptor roles 確定用戶(hù)是否具有JAAS指定的Role,否則不予執(zhí)行
Timer Interceptor timer 輸出Action執(zhí)行的時(shí)間
Token Interceptor token 通過(guò)Token來(lái)避免雙擊
Token Session Interceptor tokenSession 和Token Interceptory一樣,不過(guò)雙擊的時(shí)候把請(qǐng)求的數(shù)據(jù)存儲(chǔ)在Session中
Validation Interceptor validation 使用action-validation.xml文件中定義的內(nèi)容校驗(yàn)提交的數(shù)據(jù)
Workflow Interceptor workflow 調(diào)用Action的validate的方法,一旦有錯(cuò)返回,重新定位到INPUT頁(yè)面
Parameter Filter Interceptor N/A 從參數(shù)列表中刪除不必要的參數(shù)
Profiling Interceptor profiling 通過(guò)參數(shù)激活profile
? 每一個(gè)攔截器都可以配置參數(shù),有兩種方式配置參數(shù),一是針對(duì)每一個(gè)攔截器定義參數(shù),二是針對(duì)一個(gè)攔截器堆棧統(tǒng)一定義所有的參數(shù),例如:




或者

每一個(gè)攔截器都有兩個(gè)默認(rèn)的參數(shù):
excludeMethods - 過(guò)濾掉不使用攔截器的方法和
includeMethods – 使用攔截器的方法。
需要說(shuō)明的幾點(diǎn):
1 攔截器執(zhí)行的順序按照定義的順序執(zhí)行,例如:

的執(zhí)行順序?yàn)椋?
thisWillRunFirstInterceptor thisWillRunNextInterceptor followedByThisInterceptor thisWillRunLastInterceptor MyAction1 MyAction2 (chain) MyPreResultListener MyResult (result) thisWillRunLastInterceptor followedByThisInterceptor thisWillRunNextInterceptor thisWillRunFirstInterceptor
2 使用默認(rèn)攔截器配置每個(gè)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)”,可擴(kuò)展性是不可或缺的,因?yàn)槭郎蠜](méi)有放之四海而皆準(zhǔn)的東西。雖然,Struts 2為我們提供如此豐富的攔截器實(shí)現(xiàn),但是這并不意味我們失去創(chuàng)建自定義攔截器的能力,恰恰相反,在Struts 2自定義攔截器是相當(dāng)容易的一件事。
大家在開(kāi)始著手創(chuàng)建自定義攔截器前,切記以下原則:
攔截器必須是無(wú)狀態(tài)的,不要使用在API提供的ActionInvocation之外的任何東西。
??? 要求攔截器是無(wú)狀態(tài)的原因是Struts 2不能保證為每一個(gè)請(qǐng)求或者action創(chuàng)建一個(gè)實(shí)例,所以如果攔截器帶有狀態(tài),會(huì)引發(fā)并發(fā)問(wèn)題。
??? 所有的Struts 2的攔截器都直接或間接實(shí)現(xiàn)接口com.opensymphony.xwork2.interceptor.Interceptor。除此之外,大家可能更喜歡繼承類(lèi)com.opensymphony.xwork2.interceptor.AbstractInterceptor。
以下例子演示通過(guò)繼承AbstractInterceptor,實(shí)現(xiàn)授權(quán)攔截器。
首先,創(chuàng)建授權(quán)攔截器類(lèi)tutorial.AuthorizationInterceptor,代碼如下:?






































?? 以上代碼相當(dāng)簡(jiǎn)單,我們通過(guò)檢查session是否存在鍵為“ROLE”的字符串,判斷用戶(hù)是否登陸。如果用戶(hù)已經(jīng)登陸,將角色放到Action中,調(diào)用Action;否則,攔截直接返回Action.LOGIN字段。為了方便將角色放入Action,我定義了接口tutorial.RoleAware,代碼如下:?







?? 接著,創(chuàng)建Action類(lèi)tutorial.AuthorizatedAccess模擬訪問(wèn)受限資源,它作用就是通過(guò)實(shí)現(xiàn)RoleAware獲取角色,并將其顯示到ShowUser.jsp中,代碼如下:?




























?? 以下是ShowUser.jsp的代碼:?














??? 然后,創(chuàng)建tutorial.Roles初始化角色列表,代碼如下:?


















???? 接下來(lái),新建Login.jsp實(shí)例化tutorial.Roles,并將其roles屬性賦予<s:radio>標(biāo)志,代碼如下:?




















??? 創(chuàng)建Action類(lèi)tutorial.Login將role放到session中,并轉(zhuǎn)到Action類(lèi)tutorial.AuthorizatedAccess,代碼如下:?








































???
??? 最后,配置struts.xml文件,內(nèi)容如下:






















