什么是攔截器。
Interceptor(以下譯為攔截器)是Struts 2的一個強有力的工具,有許多功能(feature)都是構建於它之上,如國際化、校驗等。
攔截器,在AOP(Aspect-Oriented Programming)中用於在某個方法或字段被訪問之前,進行攔截然后在之前或之后加入某些操作。攔截是AOP的一種實現策略。在Webwork的中文文檔的解釋為——攔截器是動態攔截Action調用的對象。它提供了一種機制可以使開發者可以定義在一個action執行的前后執行的代碼,也可以在一個action執行前阻止其執行。同時也是提供了一種可以提取action中可重用的部分的方式。
談到攔截器,還有一個詞大家應該知道——攔截器棧(Interceptor Chain,在Struts 2中稱為攔截器棧Interceptor Stack)。攔截器棧就是將攔截器按一定的順序聯結成一個棧。在訪問被攔截的方法或字段時,攔截器鏈中的攔截器就會按其之前定義的順序被調用。
實現原理
Struts 2的攔截器實現相對簡單。當請求到達Struts 2的ServletDispatcher時,Struts 2會查找配置文件,並根據其配置實例化相對的攔截器對象,然后串成一個列表(list),最后一個一個地調用列表中的攔截器,如圖1所示。
圖1 攔截器調用序列圖
STRUTS2內建攔截器
Struts 2已經為您提供豐富多樣的,功能齊全的攔截器實現。大家可以到struts2-all-2.0.1.jar或struts2-core-2.0.1.jar包的struts-default.xml查看關於默認的攔截器與攔截器鏈的配置。
以下部分就是從struts-default.xml文件摘取的內容:
< interceptor name ="autowiring" class ="com.opensymphony.xwork2.spring.interceptor.ActionAutowiringInterceptor" />
< interceptor name ="chain" class ="com.opensymphony.xwork2.interceptor.ChainingInterceptor" />
< interceptor name ="conversionError" class ="org.apache.struts2.interceptor.StrutsConversionErrorInterceptor" />
< interceptor name ="createSession" class ="org.apache.struts2.interceptor.CreateSessionInterceptor" />
< interceptor name ="debugging" class ="org.apache.struts2.interceptor.debugging.DebuggingInterceptor" />
< interceptor name ="external-ref" class ="com.opensymphony.xwork2.interceptor.ExternalReferencesInterceptor" />
< interceptor name ="execAndWait" class ="org.apache.struts2.interceptor.ExecuteAndWaitInterceptor" />
< interceptor name ="exception" class ="com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor" />
< interceptor name ="fileUpload" class ="org.apache.struts2.interceptor.FileUploadInterceptor" />
< interceptor name ="i18n" class ="com.opensymphony.xwork2.interceptor.I18nInterceptor" />
< interceptor name ="logger" class ="com.opensymphony.xwork2.interceptor.LoggingInterceptor" />
< interceptor name ="model-driven" class ="com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor" />
< interceptor name ="scoped-model-driven" class ="com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor" />
< interceptor name ="params" class ="com.opensymphony.xwork2.interceptor.ParametersInterceptor" />
< interceptor name ="prepare" class ="com.opensymphony.xwork2.interceptor.PrepareInterceptor" />
< interceptor name ="static-params" class ="com.opensymphony.xwork2.interceptor.StaticParametersInterceptor" />
< interceptor name ="scope" class ="org.apache.struts2.interceptor.ScopeInterceptor" />
< interceptor name ="servlet-config" class ="org.apache.struts2.interceptor.ServletConfigInterceptor" />
< interceptor name ="sessionAutowiring" class ="org.apache.struts2.spring.interceptor.SessionContextAutowiringInterceptor" />
< interceptor name ="timer" class ="com.opensymphony.xwork2.interceptor.TimerInterceptor" />
< interceptor name ="token" class ="org.apache.struts2.interceptor.TokenInterceptor" />
< interceptor name ="token-session" class ="org.apache.struts2.interceptor.TokenSessionStoreInterceptor" />
< interceptor name ="validation" class ="com.opensymphony.xwork2.validator.ValidationInterceptor" />
< interceptor name ="workflow" class ="com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor" />
< interceptor name ="store" class ="org.apache.struts2.interceptor.MessageStoreInterceptor" />
< interceptor name ="checkbox" class ="org.apache.struts2.interceptor.CheckboxInterceptor" />
< interceptor name ="profiling" class ="org.apache.struts2.interceptor.ProfilingActivationInterceptor" />
工具攔截器
首先,我們先看一些公具攔截器。這些攔截器提供了輔助看法,調優以及解決問題的簡單工具。
1.timer攔截器
這個簡單的攔截器只記錄執行花費的時間。在攔截器棧中的位置決定了它實際測量了什么時間。
2.logger攔截器
這個攔截器提供了一個簡單的日志記錄,記錄了在預處理時的進入聲明,以及在后加工時的退出聲明。
數據轉移攔截器
攔截器能夠用來處理數據轉移,通過攔截器可以將數據轉移到動作上,例如從XML配置文件中的定義的參數。
1.param攔截器
他將請求參數轉移到通過valuestack公開的屬性上,攔截器不知道這些數據終究去到哪里,它只是把數據轉移到valuestack上一個匹配的屬性上。
2.static-param攔截器
它的作用和param攔截器的作用相似,不同的是參數的來源,這個攔截器轉移的參數定義在聲明性架構的動作元素中。
3.servlet-config攔截器
這個攔截器通過各種對象設置到動作必須實現的接口。
4.fileupload攔截器
fileupload攔截器將文件和元數據從多重請求轉換為常規的請求參數,以便能夠將他們像普通參數一樣設置到動作上。
struts的內建攔截器還有很多,比如workflow攔截器,validation攔截器等等,由於篇幅有限這里就不詳細介紹了,如果大家有興趣可以查閱相關資糧,比如struts2 in action 這里介紹的都很詳細,只是書翻譯的比較爛,下面開始介紹我的自定義攔截器。
自定義攔截器
在將自定義攔截器之前,讓我們先了解一下,怎么將攔截器映射到組件上。可以使用interceptor-ref 元素完成攔截器和動作的關聯。
構建自定義攔截器首先要讓自己的類實現一個interceptor接口,實現這個幾口要覆寫這個類的方法:
public String intercept(ActionInvocation actioninvocation) throws Exception {}
如果我們自定義的方法,如果想要設置和覆蓋攔截器的參數:
<interceptor-ref name="authenticationInterceptor" >
<param name = "excludeMethods">login,register</param>
</interceptor-ref>
就必須繼承MethodFilterInterceptor類,我因為這個問題浪費了我好幾個小時,才把這個問題解決,具體的攔截器類實現如下:
@Override
protected String doIntercept(ActionInvocation actioninvocation)
throws Exception {
Map session = actioninvocation.getInvocationContext().getSession();
UserDomain user = (UserDomain) session.get("user");
if (user == null) {
return Action.LOGIN;
} else {
Action action = (Action) actioninvocation.getAction();
if (action instanceof UserAware) {
((UserAware) action).setUser(user);
}
System.out.println("Logged in: interceptor");
return actioninvocation.invoke();
}
}
引入的struts.xml文件如下:
<interceptors>
<interceptor name="authenticationInterceptor"
class="com.duqiao.interceptor.AuthenticationInterceptor" />
<interceptor-stack name="duqiaoStack">
<interceptor-ref name="authenticationInterceptor" >
<param name = "excludeMethods">login,register</param>
</interceptor-ref>
<interceptor-ref name="defaultStack" />
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="duqiaoStack" />
本文部分內容引自“http://www.blogjava.net/max/archive/2006/12/06/85925.html”。max on java