? 攔截器的類(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?>?