攔截器(Interceptor)是Struts2的核心和基礎,有許多功能都是構建於它之上,如國際化、轉換器、校驗等。
截攔器是AOP的一種實現,底層通過動態代理模式完成
struts2攔截器初識
1. 如果攔截器堆棧中還有其他的Interceptor,那麼invoke()將調用堆棧中下一個Interceptor的執行。
2. 如果攔截器堆棧中只有Action了,那麼invoke()將調用Action執行。
圖中,Struts2的Interceptor一層一層,把Action包裹在最裏面。這樣的結構,大概有以下一些特點:
1) 中止整個執行,直接返回一個字符串作爲resultCode
2) 通過遞歸調用負責調用堆棧中下一個Interceptor的執行
3) 如果在堆棧內已經不存在任何的Interceptor,調用Action
<package name="default" extends="struts-default">
<interceptors>
<interceptor name=“攔截器名1” class=“攔截器實現類1"/>
<interceptor name=“攔截器名2” class=“攔截器實現類2”>
< param name= “參數名” >參數值</param>
</interceptor>
// …………其他攔截器
</interceptors>
<action name=“Action名” class=“Action類">
<interceptor-ref name="defaultStack"/>
<interceptor-ref name=“攔截器名1”/>
<interceptor-ref name="攔截器名2">
< param name= “參數名” >參數值</param>
</interceptor-ref>
// …………Action其他配置
</action>
</package>
配置和使用攔截棧<package name="default" extends="struts-default">
<interceptors>
<interceptor name=“攔截器名1” class=“攔截器實現類1"/>
<interceptor name=“攔截器名2” class=“攔截器實現類2”/>
<interceptor name=“攔截器名3” class=“攔截器實現類3”/>
<interceptor name=“攔截器名3” class=“攔截器實現類4”/>
// …………其他攔截器
<interceptor-stack name=“myStack1”> //自定義攔截器棧1
<interceptor-ref name=“攔截器名1”/>
<interceptor-ref name="defaultStack"/>
</interceptor-stack>
<interceptor-stack name=“myStack2”> //自定義攔截器棧2
<interceptor-ref name=“攔截器名2”/>
<interceptor-ref name=“攔截器名3”/>
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="myStack1"/>
<action name=“Action名” class=“Action類">
<interceptor-ref name=“myStack2"/>
<interceptor-ref name=“攔截器名4”/>
// …………Action其他配置
</action>
</package>
修改
package的默認攔截器會應用到package中的所有Action。
自定義攔截器做爲“框架(framework)”,可擴展性是不可或缺的。雖然,Struts 2爲我們提供了豐富的攔截器實現,但是這並不意味我們失去創建自定義攔截器的能力,恰恰相反,在Struts 2自定義攔截器非常容易。
自定義攔截器攔截器對Action中方法進行攔截自定義攔截器及其使用:1.直接或間接實現接口com.opensymphony.xwork2.interceptor.Interceptor2.或者繼承類com.opensymphony.xwork2.interceptor.AbstractInterceptor3.通過<interceptor>元素來定義攔截器4.通過<interceptor-ref>元素來使用攔截器Interceptor接口中定義了三個方法:void init():在攔截器初始化之後,在執行攔截之前,系統調用該方法。對於一個攔截器而言,init方法只會被調用一次。String intercept(ActionInvocation invocation) throws Exception:該方法是攔截器的攔截方法,返回一個字符串,系統將會跳轉到該字符串對應的視圖資源。該方法的ActionInvocation參數包含了被攔截的Action的引用,可以通過該對象的invoke方法,將控制權轉給下一個攔截器或者轉給Action的execute方法。void destroy():該方法與init方法對應,在攔截器示例被銷燬之前,系統將會調用該方法。public class CustomInterceptor1 implements Interceptor {
public String intercept(ActionInvocation invocation) throws Exception {
/*Action前置攔截
*/
System.out.println(“========我是一個攔截器========”);
String result = invocation.invoke();
/*Action後置攔截
*/
System.out.println("========我是一個攔截器========");
return result;
}
}
<interceptor-ref name="execAndWait">
<!-- 等待時間,執行時間沒有超過此值,將不顯示等待畫面 (毫秒)-->
<param name="delay">1000</param>
<!-- 間隔檢查時間,檢查後臺進程有沒有執行完畢,如果完成了它就立刻返回,不用等到等待,用戶不會看到等待畫面 -->
<param name="delaySleepInterval">50</param>
</interceptor-ref>
<result name=“wait”>wait.jsp</result>
1、在提交頁面如登錄頁面中加入token標記<s:token></s:token>
2、在struts.xml 中配置tokenInterceptor攔截器和配置invoke.token信息。
<result name="success">/login/welcome.jsp</result>
<result name="invalid.token">/login/wrong.jsp</result>
<interceptor-ref name="defaultStack"/>
<!-- 配置token攔截器-->
<interceptor-ref name="token"/>
1、在提交頁面如登錄頁面中加入token標記<s:token></s:token>
2、在struts.xml 中配置tokenInterceptor攔截器:
<interceptor-ref name= "tolenSession"/>
當檢查到重複提交後,總會返回到第一次成功提交的頁面。