Struts2學習筆記 (四) Struts2框架核心:攔截器使用配置解析和常見bug

目錄

基本概念及原理

自定義攔截器:

使用攔截器

重複提交數據:



基本概念及原理

含義

Struts 2攔截器,是Struts2的核心和基礎。

爲AOP的一種實現,底層通過動態代理動態完成。反射。

訪問action之後,需要經過層層攔截器。

完成某些功能的類,以可插拔的方式放在配置前,後。

官方定義

動態攔截Action調用的對象,提供機制,定義代碼,使其在Action前後被調用,也可以在Action執行之前阻止其執行。同時提供一種可以提取Action中可重用的方式。

攔截器棧:多個攔截器組合的集合體,將這些攔截器按照一定的順序鏈接成鏈。

圖:後進先出棧

 

攔截器原理:和過濾器的功能類似,一個攔截器在一個攔截棧中有什麼功能:1,可以調用下方的攔截器,有時可以判斷請求是否通過,下面如果沒有攔截器的話調用資源Action。

攔截器代碼:在struts-default.xml中查看。

interceptors器;

interceptor-stack棧;

default-interceptor-ref默認攔截器配置。

典型的責任鏈模式,職責鏈,判斷在運行過程中實時選擇。 代表:異常

每個元素有不同職責,將他們納入鏈式結構,每個元素負責鏈式結構下一個元素的執行調用。

思想:將複雜的系統分而治之,使每個部分的邏輯能夠高度重用並增強他的拓展性。


自定義攔截器:

三個步驟:

1.直接或間接實現接口,(適配器模式)com.opensymphony.xwork2.interceptor.Interceptor,實現一個接口必須實現接口中的所有方法。如圖:

 

或者繼承繼承類  com.opensymphony.xwork2.interceptor.AbstractInterceptor實現一個繼承類只需要實現需要的方法。

2,通過<interceptor>元素來定義攔截器

3,通過<interceptor-ref>元素使用攔截器

struts.xml中 定義攔截器,定義在action標籤之前,並在action中配置攔截器。新建Invocation。先定義一個新的攔截器類MyInterceptor,繼承Interceptor接口中的多個方法,也可繼承AbstractInterceptor中的方法,繼承到的方法,將intercept方法中在攔截器獲得攔截結果的前後打入輸出,調試程序觀察出攔截器出入的順序。

public String intercept(ActionInvocation invocation) throws Exception {

         System.out.println("method start");

         String result=invocation.invoke();

         System.out.println("method end");

         return result;

    }

配置struts.xml攔截器的代碼:

<interceptors>

          <interceptor name="inter01" class="com.it.struts.inter.MyInterceptor"></interceptor>

</interceptors>

使用攔截器

加入攔截器出現了問題,當引用自定義攔截器時,默認攔截器將失效。此時需要在struts.xml中手動引用默認攔截器。

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

在action標籤中添加默認攔截器的引用代碼:

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

攔截器1成功,並且按出入順序打印出標記:

 

攔截棧的運用:

 

也可以將兩條引用語句從action配置中取出並放入攔截棧中,稱爲自定義攔截棧,命名爲myStack。

<interceptors>

           <!--  自定義攔截器 -->

           <interceptor name="inter01" class="com.it.struts.inter.MyInterceptor"></interceptor>

           

           <!-- 自定義攔截棧 -->

           <interceptor-stack name="myStack">

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

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

           

           </interceptor-stack>

        </interceptors>

並在action中引用myStack攔截棧。

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

  在定義兩個攔截器的時候,配置完成後,運行獲得結果。

獲取數據的順序爲後進先出,符合攔截棧的基本特性。


提出問題:在package中的多個action想要引用同名攔截棧myStack,只需要在action標籤前面添加語句:

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

添加後action中的調用棧語句可以刪除。

攔截器對所有方法都會攔截,但是隻想要攔截單獨的方法。提供MethodFilterInterceptor類

其中有兩個方法:exclude爲顯示想要攔截的方法,include爲顯示不想要攔截的方法。

在MethodFilterInterceptor類中有兩個的方法,攔截和不攔截,在自定義攔截器中你想要操作的攔截器標籤下添加param標籤: 

<interceptor name="inter03" class="com.it.struts.inter.MyInterceptor3">

           <param name="excludeMethods">login</param></interceptor>

表示攔截器3不進行攔截,此時就不會通過攔截器3。includeMethods方法同理。


重複提交數據:

在提交數據之後,刷新頁面會使數據再次提交,數據會提交兩次,造成錯誤。

可以用重定向sendRecdient,將地址定向到新的頁面。但是某些情況只能使用請求轉發Dispacther。

如何解決:在第一次打開頁面後,向session中存值,同時保存,提交頁面時將提交頁面的值和session的值進行比對,如果一致,代表第一次提交,運行進入Action,第一次提交後session清空,第二次打開頁面,表單中的值還在,session中的值已經沒有了,兩個對比之下不同,便可以跳轉至錯誤頁面。

解決方法:

使用Strut2框架中自帶的tokenInterceptor攔截器。

1,在提交頁面如登錄頁面表單中加入token標記。

在form表單中添加 <s:token></s:token>標籤。

2,在struts.xml中配置tokenInterceptor攔截器和配置invoke.token信息。

在Struts2中有一個攔截器token,需要配置進棧。

<interceptor name="token" class="org.apache.struts2.interceptor.TokenInterceptor"/>

最後在token接口中找到結果名稱,類型爲redirect。

 

 

<result name="invalid.token" type="redirect">login.jsp</result>

這樣,就可以解決在Struts2框架中關於數據由於重複刷新而導致重複提交數據的情況。

 

 

 

 

 

發佈了23 篇原創文章 · 獲贊 10 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章