天天看點

【struts2】預定義攔截器

  1)預定義攔截器

  Struts2有預設的攔截器配置,也就是說,雖然我們沒有主動去配置任何關于攔截器的東西,但是Struts2會使用預設引用的攔截器。由于Struts2的預設攔截器聲明和引用都在這個Struts-default.xml裡面,是以我們需要到這個檔案的struts-default包裡去看一下。定義如下:

View Code

params攔截器

  這個攔截器是必不可少的,因為就是由它偷偷的把請求參數設定到相應的Action的屬性去的,并自動進行類型轉換。

staticParams攔截器

  将struts.xml配置檔案裡定義的Action參數,設定到對應的Action執行個體中,Action參數使用<param>标簽,是<action>标簽的子元素。struts.xml的示例如下:

  這要求Action中一定要有一個account的屬性,并有相應的getter/setter方法。運作的時候,Action的account屬性在初始化過後,會接到這裡的指派“test”。

  注意:params攔截器和staticParams攔截器都會為Action的屬性指派,如果碰到了都要賦同一個值呢,比如request裡面有account參數,而struts.xml中也有account參數,最終的值是誰?其實是Action初始化過後,就會把struts.xml中配置的資料設定到Action執行個體中相應的屬性上去。然後,把使用者請求的資料設定到Action執行個體中相應的屬性上去。很明顯最後的值是使用者請求中account的資料。

timer攔截器

  該攔截器可以記錄ActionInvocation餘下部分執行的時間,并做為日志資訊記錄下來,便于尋找性能瓶頸。也就是說,該攔截器可以記錄Action運作的時間。

logger攔截器

  在日志資訊中輸出要執行的Action資訊

,這樣,在調試的時候,就能很快的定位到這個對應的Action了。

  2)攔截器配置說明

<interceptor>元素用來定義一個攔截器,這裡僅僅是一個定義,還沒有任何一個Action來引用它。裡面的name屬性作為唯一标志,而class屬性就是這個攔截器的實作類。攔截器的實作類都應該是com.opensymphony.xwork2.interceptor.Interceptor這個接口的實作類。

<interceptor-stack>定義了一個攔截器棧,這個棧中可以引用其他已經定義好的攔截器。攔截器棧簡化了動作類Action在引用攔截器時的操作。

因為大多數動作類Action在引用攔截器的時候都不會僅僅引用一個攔截器,而是引用一組攔截器,而多個動作類Action大概又會引用同一組攔截器,這時候,為了引用的友善,可以把多個攔截器組合成一個攔截器棧。Action在引用的時候,隻需要引用這個攔截器棧就可以了,而不是引用每一個攔截器。下面看一下struts-2.1.dtd對于<action>元素的定義:

  action元素後面出現的interceptor-ref子元素後面用*來修飾,這說明一個action元素可以有不限個數的interceptor-ref子元素。那麼在<action>元素中,如何使用<interceptor-ref>子元素呢?其實很簡單,隻需要在<action>元素中,配置需要的<interceptor-ref>子元素就可以了,<interceptor-ref>子元素裡面配置需要使用的攔截器的名稱,比如:

  <interceptor-ref>子元素中的name,不僅僅可以是一個已經定義好的攔截器的名稱,還可以是一個已經定義好的攔截器棧的名稱。上面的示例,就引用了一個攔截器和一個攔截器棧。

<default-interceptor-ref>在包上聲明包内所有的Action都使用的攔截器

  先看一下struts-2.1.dtd對于<package>元素的定義:

  其實,在配置自己的package的時候所擴充的struts-default包裡面,就已經定義了一個<default-interceptor-ref>,在Struts-default.xml中定義的struts-default包内,有如下定義:

  正是因為有這個定義,我們都沒有主動去配置攔截器,但實際上,是有攔截器在運作并執行很重要的工作,隻不過是使用的預設的攔截器,我們不知道罷了。

  3)攔截器的調用順序

  在學習了預定義攔截器的配置使用之後,接下來看看<action>元素引用攔截器的調用順序。在拿到一個動作類的聲明<action>元素後,如何找到它引用的攔截器呢?

  1:首先,要找它自己有沒有聲明攔截器的引用,即<action>元素有沒有<interceptor-ref>子元素,如果有,則不用繼續再找,直接使用這些攔截器,如果沒有,下一步。

  2:其次,找這個<action>所在的包有沒有聲明預設的攔截器引用,即<package>元素的<default-interceptor-ref>子元素,

如果有,則不用繼續再找,直接使用這些攔截器,如果沒有,下一步。

3:最後,遞歸地尋找這個包的父包有沒有聲明預設的攔截器引用,直到找到有攔截器引用就為止。

       特别注意:這三個地方的定義是覆寫的關系,什麼意思呢?就是如果<action>裡面聲明了攔截器引用,那麼就以它的為準,其他的定義就無效了。也即是<action>裡面的攔截器引用聲明會覆寫<package>裡面的預設攔截器聲明,而<package>裡面的預設攔截器聲明又會覆寫父包的<package>裡面的預設攔截器聲明,以此類推。

  4)全局攔截器的配置

  參考資料: