struts2攔截器interceptor的配置方法及使用


 

轉:

標簽:

it

365

分類: Struts2

 

 NormalText Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 
<struts> 

    <package name="struts2" extends="struts-default"> 

        <interceptors> 

            <interceptor name="myInterceptor" class="edu.hust.interceptor.MyInterceptor"></interceptor> 

        </interceptors>

        <action name="register" class="edu.hust.action.RegisterAction"> 

            <result name="input">/register.jsp</result> 

            <result>/result.jsp</result>           

            <!-- 在自定義interceptor並將其ref時, 系統會覆蓋掉默認的interceptor-stack(defaultStack), 為了保證系統默認的defaultStack不受印象, 我們需要顯式的將其引入 --> 

            <!-- 注意兩個interceptor-ref的順序, 順序不同, 執行效果也不同: 先配置的先執行/后配置的先退出(先進后出) --> 

            <interceptor-ref name="defaultStack"></interceptor-ref> 

            <interceptor-ref name="myInterceptor"></interceptor-ref> 

        </action> 

    </package> 

</struts>

方法2. 配置攔截器棧(即將多個interceptor串聯的一種元素)。然后在ion>中引入該攔截器棧就可以了。

 

 NormalText Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 
<struts> 

    <package name="struts2" extends="struts-default">     

        <interceptors> 

            <interceptor name="myInterceptor" class="edu.hust.interceptor.MyInterceptor"></interceptor>       

            <interceptor-stack name="myInterceptorStack"> 

                <interceptor-ref name="myInterceptor"></interceptor-ref> 

                <interceptor-ref name="defaultStack"></interceptor-ref> 

            </interceptor-stack> 

        </interceptors>    

        <action name="register" class="edu.hust.action.RegisterAction"> 

            <result name="input">/register.jsp</result> 

            <result>/result.jsp</result>             

            <interceptor-ref name="myInterceptorStack"></interceptor-ref> 

        </action> 

    </package> 

</struts>

 

 NormalText Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 
<struts> 

    <package name="struts2" extends="struts-default">     

        <interceptors> 

            <interceptor name="myInterceptor" class="edu.hust.interceptor.MyInterceptor"></interceptor> 

            <interceptor-stack name="myInterceptorStack"> 

                <interceptor-ref name="myInterceptor"></interceptor-ref> 

                <interceptor-ref name="defaultStack"></interceptor-ref> 

            </interceptor-stack> 

        </interceptors>

        <!-- 此默認interceptor是針對所有action的 --> 

        <!-- 如果某個action中引入了interceptor, 則在這個action中此默認interceptor就會失效 --> 

        <default-interceptor-ref name="myInterceptorStack"></default-interceptor-ref>         

        <action name="register" class="edu.hust.action.RegisterAction"> 

            <result name="input">/register.jsp</result> 

            <result>/result.jsp</result> 

        </action>      

    </package> 

</struts>

看到網上很多介紹關於攔截器的文章,感覺都不錯,但是都沒有很詳細全面的介紹,所以我就博眾家之長,呵呵,寫了篇關於struts攔截器的東西。 
struts2攔截器interceptor的配置方法及使用


攔截器的工作原理如上圖,在工作的時候每一個Action請求都被包裝在一堆攔截器的內部。攔截器可以在Action執行直線做相似的操作也可以在Action執行直后做回收操作。 

每一個Action既可以將操作轉交給下面的攔截器,Action也可以直接退出操作返回客戶既定的畫面。 

下面我們來講講如何使用struts2攔截器,或者是自定義攔截器。 

先說說使用Struts自帶的攔截器: 
在Struts2中已經在struts-default.xml中預定義了一些自帶的攔截器,如timer、params等。如果在標簽中繼承struts-default,則當前package就會自動擁有struts-default.xml中的所有配置。代碼如下: 

...  

在struts-default.xml中有一個默認的引用,在默認情況下(也就是中未引用攔截器時)會自動引用一些攔截器。這個默認的攔截器引用如下: 

Xml代碼  
  1. <</span>interceptor-stack name="defaultStack">  
  2. <</span>interceptor-ref name="exception"/>  
  3. <</span>interceptor-ref name="alias"/>  
  4. <</span>interceptor-ref name="servletConfig"/>  
  5. <</span>interceptor-ref name="prepare"/>  
  6. <</span>interceptor-ref name="i18n"/>  
  7. <</span>interceptor-ref name="chain"/>  
  8. <</span>interceptor-ref name="debugging"/>  
  9. <</span>interceptor-ref name="profiling"/>  
  10. <</span>interceptor-ref name="scopedModelDriven"/>  
  11. <</span>interceptor-ref name="modelDriven"/>  
  12. <</span>interceptor-ref name="fileUpload"/>  
  13. <</span>interceptor-ref name="checkbox"/>  
  14. <</span>interceptor-ref name="staticParams"/>  
  15. <</span>interceptor-ref name="params">  
  16. <</span>param name="excludeParams">dojo\..*</</span>param>  
  17. </</span>interceptor-ref>  
  18. <</span>interceptor-ref name="conversionError"/>  
  19. <</span>interceptor-ref name="validation">  
  20. <</span>param name="excludeMethods">input,back,cancel,browse</</span>param>  
  21. </</span>interceptor-ref>  
  22. <</span>interceptor-ref name="workflow">  
  23. <</span>param name="excludeMethods">input,back,cancel,browse</</span>param>  
  24. </</span>interceptor-ref>  
  25. </</span>interceptor-stack>  

上面在defaultStack中引用的攔截器都可以在中不經過引用就可以使用(如果在中引用了任何攔截器后,要使用在defaultStack中定義的攔截器,也需要在中重新引用,在后面的“二、通過請求調用Action的setter方法(params)”將詳細講解)。 
下面我們來看幾個簡單的攔截器的使用方法。 

一、記錄攔截器和execute方法的執行時間(timer攔截器) 

timer是Struts2中最簡單的攔截器,這個攔截器對應的類是com.opensymphony.xwork2.interceptor.TimerInterceptor。它的功能是記錄execute方法和其他攔截器(在timer后面定義的攔截器)的intercept方法執行的時間總和。如下面的配置代碼所示: 

Xml代碼  
  1. <</span>action name="first" class="action.FirstAction">  
  2. <</span>interceptor-ref name="logger"/>  
  3. <</span>interceptor-ref name="timer" />  
  4. </</span>action>  

由於在timer后面沒有其他的攔截器定義,因此,timer只能記錄execute方法的執行時間,在訪問first動作時,會在控制台輸出類似下面的一條信息: 

信息: Executed action [/test/first!execute] took 16 ms. 

在使用timer攔截器時,需要commons-logging.jar的支持。將logger引用放到timer的后面,就可以記錄logger攔截器的intercept方法和Action的execute方法的執行時間總和,代碼如下: 

Xml代碼  
  1. <</span>action name="first" class="action.FirstAction">  
  2. <</span>interceptor-ref name="timer" />  
  3. <</span>interceptor-ref name="logger"/>  
  4. </</span>action>  

大家可以使用如下的Action類來測試一下timer攔截器: 

Java代碼  
  1. package action;  
  2. import com.opensymphony.xwork2.ActionSupport;  
  3. public class FirstAction extends ActionSupport            
  4. {  
  5. public String execute() throws Exception  
  6.        {  
  7. 2000); // 延遲2秒  
  8. return null;  
  9.   
  10. }  

如果只記錄execute方法的執行時間,一般會輸出如下的信息: 

信息: Executed action [/test/first!execute] took 2000 ms. 

二、通過請求調用Action的setter方法(params) 


    當客戶端的一個form向服務端提交請求時,如有一個textfield,代碼如下: 

Jsp代碼  
  1. "/test">  
  2. "name"/>  
  3.   

在提交后,Struts2將會自動調用first動作類中的setName方法,並將name文本框中的值通過setName方法的參數傳入。實際上,這個操作是由params攔截器完成的,params對應的類是com.opensymphony.xwork2.interceptor.ParametersInterceptor。由於params已經在defaultStack中定義,因此,在未引用攔截器的中是會自動引用params的,如下面的配置代碼,在訪問first動作時,Struts2是會自動執行相應的setter方法的。 

 

    ... ... 

 

但如果在中引用了其他的攔截器,就必須再次引用params攔截器,Struts2才能調用相應的setter方法。如下面的配置代碼所示: 

Xml代碼  
  1. <</span>action name="first" class="action.FirstAction">  
  2. <</span>interceptor-ref name="timer" />  
  3. <</span>interceptor-ref name="params"/>  
  4. </</span>action>  

三、通過配置參數調用Action的setter方法(static-params) 

    static-params攔截器可以通過配置標簽來調用Action類的相應的setter方法,static-params攔截器對應的類是com.opensymphony.xwork2.interceptor.StaticParametersInterceptor。 
    下面配置代碼演示了如何使用static-params攔截器: 

Xml代碼  
  1. <</span>action name="first" class="action.FirstAction">  
  2. <</span>interceptor-ref name="timer" />  
  3. <</span>param name="who">比爾</</span>param>  
  4. <</span>interceptor-ref name="params"/>  
  5. <</span>interceptor-ref name="static-params"/>  
  6. </</span>action>  

如果first動作使用上面的配置,在訪問first動作時,Struts2會自動調用setWho方法將“比爾”作為參數值傳入setWho方法。 

四、使用攔截器棧 

為了能在多個動作中方便地引用同一個或幾個攔截器,可以使用攔截器棧將這些攔截器作為一個整體來引用。攔截器棧要在標簽中使用和子標簽來定義。代碼如下: 

Xml代碼  
  1. <</span>package name="demo" extends="struts-default" >  
  2. <</span>interceptors>  
  3. <</span>interceptor-stack name="mystack">  
  4. <</span>interceptor-ref name="timer" />  
  5. <</span>interceptor-ref name="logger" />  
  6. <</span>interceptor-ref name="params" />  
  7. <</span>interceptor-ref name="static-params" />  
  8. </</span>interceptor-stack>  
  9. </</span>interceptors>  
  10.     <</span>action name="first" class="action.FirstAction">  
  11. <</span>param name="who">比爾</</span>param>  
  12. <</span>interceptor-ref name="mystack"/>              
  13. </</span>action>  
  14. </</span>package>  

這樣以來,我們就可以象使用攔截器一樣使用攔截器棧。 





如何自定義一個攔截器? 
自定義一個攔截器,我們需要三步就可以完成了: 
1 自定義一個實現Interceptor接口(或者繼承自AbstractInterceptor)的類。 
2 在strutx.xml中注冊上一步中定義的攔截器。 
3 在需要使用的Action中引用上述定義的攔截器,為了方便也可將攔截器定義為默認的攔截器,這樣在不加特殊聲明的情況下所有的Action都被這個攔截器攔截。 

Interceptor接口聲明了三個方法: 

Java代碼  
  1. public interface Interceptor extends Serializable {  
  2.     void destroy();  
  3.     void init();  
  4.     String intercept(ActionInvocation invocation) throws Exception;  
  5. }  

Init方法在攔截器類被創建之后,在對Action鏡像攔截之前調用,相當於一個post-constructor方法,使用這個方法可以給攔截器類做必要的初始話操作。 

Destroy方法在攔截器被垃圾回收之前調用,用來回收init方法初始化的資源。 

Intercept是攔截器的主要攔截方法,如果需要調用后續的Action或者攔截器,只需要在該方法中調用invocation.invoke()方法即可,在該方法調用的前后可以插入Action調用前后攔截器需要做的方法。如果不需要調用后續的方法,則返回一個String類型的對象即可,例如Action.SUCCESS。 
另外AbstractInterceptor提供了一個簡單的Interceptor的實現,這個實現為: 

Java代碼  
  1. public abstract class AbstractInterceptor implements Interceptor {  
  2.      public void init() {  
  3.      
  4. public void destroy() {  
  5.    
  6.     public abstract String intercept(ActionInvocation invocation) throws Exception;  
  7. }  

在不需要編寫init和destroy方法的時候,只需要從AbstractInterceptor繼承而來,實現intercept方法即可。 

我們嘗試編寫一個Session過濾用的攔截器,該攔截器查看用戶Session中是否存在特定的屬性(LOGIN屬性)如果不存在,中止后續操作定位到LOGIN,否則執行原定操作,代碼為: 

Java代碼  
  1. public class CheckLoginInterceptor extends AbstractInterceptor {  
  2. public static final String LOGIN_KEY = "LOGIN";  
  3. public static final String LOGIN_PAGE = "global.login";  
  4.     public String intercept(ActionInvocation actionInvocation) throws Exception {  
  5.         System.out.println("begin check login interceptor!");  
  6. // 對LoginAction不做該項攔截  
  7.         if (action instanceof LoginAction) {  
  8. "exit check login, because this is login action.");  
  9. return actionInvocation.invoke();  
  10.    
  11. // 確認Session中是否存在LOGIN  
  12.         String login = (String) session.get(LOGIN_KEY);  
  13. if (login != null && login.length() > 0) {  
  14. // 存在的情況下進行后續操作。  
  15. "already login!");  
  16. return actionInvocation.invoke();  
  17. else {  
  18. // 否則終止后續操作,返回LOGIN  
  19. "no login, forward login page!");  
  20. return LOGIN_PAGE;  
  21.     }  
  22. }  

注冊攔截器 

Xml代碼  
  1. <</span>interceptors>  
  2. <</span>interceptor  
  3. class="com.jpleasure.teamware.util.CheckLoginInterceptor"/>  
  4. <</span>interceptor-stack name="teamwareStack">  
  5. <</span>interceptor-ref name="login"/>  
  6. <</span>interceptor-ref name="defaultStack"/>  
  7. </</span>interceptor-stack>  
  8. </</span>interceptors>  

將上述攔截器設定為默認攔截器: 

Java代碼  
  1. -interceptor-ref name="teamwareStack"/>  

這樣在后續同一個package內部的所有Action執行之前都會被login攔截。 

注冊並引用Interceptor 

Xml代碼  
  1. <</span>package name="default" extends="struts-default">  
  2. <</span>interceptors>  
  3. <</span>interceptor name="timer" class=".."/>  
  4. <</span>interceptor name="logger" class=".."/>  
  5. </</span>interceptors>  
  6.    <</span>action name="login" class="tutorial.Login">  
  7. <</span>interceptor-ref name="timer"/>  
  8. <</span>interceptor-ref name="logger"/>  
  9. <</span>result name="input">login.jsp</</span>result>  
  10. <</span>result name="success"  
  11. type="redirect-action">/secure/home</</span>result>  
  12. </</span>action>  
  13. </</span>package>  
  14.    

可以將多個攔截器合並在一起作為一個堆棧調用,當一個攔截器堆棧被附加到一個Action的時候,要想Action執行,必須執行攔截器堆棧中的每一個攔截器。 

Xml代碼  
  1. <</span>package name="default" extends="struts-default">  
  2. <</span>interceptors>  
  3. <</span>interceptor name="timer" class=".."/>  
  4. <</span>interceptor name="logger" class=".."/>  
  5. <</span>interceptor-stack name="myStack">  
  6. <</span>interceptor-ref name="timer"/>  
  7. <</span>interceptor-ref name="logger"/>  
  8. </</span>interceptor-stack>  
  9. </</span>interceptors>  
  10.     <</span>action name="login" class="tutuorial.Login">  
  11. <</span>interceptor-ref name="myStack"/>  
  12. <</span>result name="input">login.jsp</</span>result>  
  13. <</span>result name="success"  
  14. type="redirect-action">/secure/home</</span>result>  
  15. </</span>action>  
  16. </</span>package>  



每一個攔截器都可以配置參數,有兩種方式配置參數,一是針對每一個攔截器定義參數,二是針對一個攔截器堆棧統一定義所有的參數,例如: 

Xml代碼  
  1. <</span>interceptor-ref name="validation">  
  2. <</span>param name="excludeMethods">myValidationExcudeMethod</</span>param>  
  3. </</span>interceptor-ref>  
  4. <</span>interceptor-ref name="workflow">  
  5. <</span>param name="excludeMethods">myWorkflowExcludeMethod</</span>param>  
  6. </</span>interceptor-ref>  

或者 

Xml代碼  
  1. <</span>interceptor-ref name="defaultStack">  
  2. <</span>param name="validation.excludeMethods">myValidationExcludeMethod</</span>param>  
  3. <</span>param name="workflow.excludeMethods">myWorkflowExcludeMethod</</span>param>  
  4. </</span>interceptor-ref>  

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

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

Xml代碼  
  1. <</span>interceptor-stack name="xaStack">  
  2. <</span>interceptor-ref name="thisWillRunFirstInterceptor"/>  
  3. <</span>interceptor-ref name="thisWillRunNextInterceptor"/>  
  4. <</span>interceptor-ref name="followedByThisInterceptor"/>  
  5. <</span>interceptor-ref name="thisWillRunLastInterceptor"/>  
  6. </</span>interceptor-stack>  

的執行順序為: 

Xml代碼  
  1.   thisWillRunNextInterceptor  
  2.       thisWillRunLastInterceptor  
  3.         MyAction2 (chain)  
  4.         MyResult (result)  
  5.     followedByThisInterceptor  
  6. thisWillRunFirstInterceptor  

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

Xml代碼  
  1. <</span>action name="login"  class="tutorial.Login">  
  2. <</span>interceptor-ref name="timer"/>  
  3. <</span>interceptor-ref name="logger"/>  
  4. <</span>interceptor-ref name="default-stack"/>  
  5.      <</span>result name="input">login.jsp</</span>result>  
  6. <</span>result type="redirect-action">/secure/home</</span>result>  
  7. </</span>action>  

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

Xml代碼  
  1. <</span>interceptors>  
  2. <</span>interceptor-stack name="myStack">  
  3. <</span>interceptor-ref name="timer"/>  
  4. <</span>interceptor-ref name="logger"/>  
  5. <</span>interceptor-ref name="default-stack"/>  
  6. </</span>interceptor-stack>  
  7. </</span>interceptors>  
  8. <</span>default-interceptor-ref name="myStack"/>  
  9. <</span>action name="login"  class="tutorial.Login">  
  10. <</span>result name="input">login.jsp</</span>result>  
  11. <</span>result type="redirect-action">/secure/home</</span>result>  
  12. </</span>action>  

3 如何訪問HttpServletRequest,HttpServletResponse或者HttpSession 
有兩種方法可以達到效果,使用ActionContext: 

Java代碼  
  1. Map attibutes = ActionContext.getContext().getSession();  

或者實現相應的接口: 

Java代碼  
  1. HttpServletRequest     ServletRequestAware  
  2. HttpServletResponse    ServletResponseAware  


Struts2(XWork)提供的攔截器的功能說明: 

      攔截器                名字                       說明
    • Alias Interceptor——alias——在不同請求之間將請求參數在不同名字件轉換,請求內容不變
    • Chaining Interceptor——chain——讓前一個Action的屬性可以被后一個Action訪問,現在和chain類型的result()結合使用。
    • Checkbox Interceptor——checkbox——添加了checkbox自動處理代碼,將沒有選中的checkbox的內容設定為false,而html默認情況下不提交沒有選中的checkbox。
    • Cookies Interceptor—— Cookies—— 使用配置的name,value來是指cookies
    • Conversion Error Interceptor—— conversionError—— 將錯誤從ActionContext中添加到Action的屬性字段中。
    • Create Session Interceptor—— createSession—— 自動的創建HttpSession,用來為需要使用到HttpSession的攔截器服務。
    • Debugging Interceptor—— 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得到的結果放在Value Stack中。
    • Scoped Model Driven—— scoped-model-driven—— 如果一個Action實現了ScopedModelDriven,則這個攔截器會從相應的Scope中取出model調用Action的setModel方法將其放入Action內部。
    • Parameters Interceptor—— params—— 將請求中的參數設置到Action中去。
    • Prepare Interceptor—— Prepare—— 如果Acton實現了Preparable,則該攔截器調用Action類的prepare方法。
    • Scope Interceptor—— Scope—— 將Action狀態存入session和application的簡單方法。
    • Servlet Config Interceptor—— servletConfig—— 提供訪問HttpServletRequest和HttpServletResponse的方法,以Map的方式訪問。
    • Static Parameters Interceptor—— staticParams—— 從struts.xml文件中將中的中的內容設置到對應的Action中。
    • Roles Interceptor—— roles—— 確定用戶是否具有JAAS指定的Role,否則不予執行。
    • Timer Interceptor—— timer—— 輸出Action執行的時間
    • Token Interceptor—— token—— 通過Token來避免雙擊
    • Token Session Interceptor—— tokenSession—— 和Token Interceptor一樣,不過雙擊的時候把請求的數據存儲在Session中
    • Validation Interceptor—— validation—— 使用action-validation.xml文件中定義的內容校驗提交的數據。
    • Workflow Interceptor—— workflow—— 調用Action的validate方法,一旦有錯誤返回,重新定位到INPUT畫面
    • Parameter Filter Interceptor—— N/A—— 從參數列表中刪除不必要的參數
    • Profiling Interceptor—— profiling—— 通過參數激活profile


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM