struts.xml配置文件4_下

攔截器(Interceptor)配置

       上節簡單地介紹了Action的配置,這節簡單介紹一下攔截器的配置。


1 攔截器棧的配置

       顧名思義,攔截器就是在action的執行前後實行攔截,加入某些操作。攔截器類似於servlet的過濾器。它們是按照定義的順序依次執行的。每一個攔截器訪問的都是相同的ActionInvocation,就像每個過濾器訪問的都是同一個Request。攔截器是通過攔截器棧進行組織的,攔截器棧組織了一系列的攔截器的集合。

       查看struts-default.xml文件的struts-default包,可以看到有兩個元素<interceptors>和<interceptor-stack>

  <interceptors>元素:定義攔截器的名字和類

  <interceptor-stack>元素:將特定的攔截器和攔截器棧組織在一起(攔截器棧中可以包含攔截器棧)

       在struts-default.xml文件中已經定義了一些攔截器:


Xml代碼  收藏代碼
  1. <interceptorname ="alias"class="com.opensymphony.xwork2.interceptor.AliasInterceptor"/>

  2. <interceptorname ="autowiring"class="com.opensymphony.xwork2.spring.interceptor.ActionAutowiringInterceptor"/>

  3. <interceptorname ="chain"class="com.opensymphony.xwork2.interceptor.ChainingInterceptor"/>

  4. <interceptorname ="conversionError"class="org.apache.struts2.interceptor.StrutsConversionErrorInterceptor"/>

  5. <interceptorname ="createSession"class="org.apache.struts2.interceptor.CreateSessionInterceptor"/>

  6. <interceptorname ="debugging"class ="org.apache.struts2.interceptor.debugging.DebuggingInterceptor"/>

  7. <interceptorname ="external-ref"class="com.opensymphony.xwork2.interceptor.ExternalReferencesInterceptor"/>

  8. <interceptorname ="execAndWait"class="org.apache.struts2.interceptor.ExecuteAndWaitInterceptor"/>

  9. <interceptorname ="exception"class="com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor"/>

  10. <interceptorname ="fileUpload"class="org.apache.struts2.interceptor.FileUploadInterceptor"/>

  11. <interceptorname ="i18n"class ="com.opensymphony.xwork2.interceptor.I18nInterceptor"/>

  12. <interceptorname ="logger"class="com.opensymphony.xwork2.interceptor.LoggingInterceptor"/>

  13. <interceptorname ="model-driven"class="com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor"/>

  14. <interceptorname ="scoped-model-driven"class="com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor"/>

  15. <interceptorname ="params"class="com.opensymphony.xwork2.interceptor.ParametersInterceptor"/>

  16. <interceptorname ="prepare"class ="com.opensymphony.xwork2.interceptor.PrepareInterceptor"/>

  17. <interceptorname ="static-params"class="com.opensymphony.xwork2.interceptor.StaticParametersInterceptor"/>

  18. <interceptorname ="scope"class="org.apache.struts2.interceptor.ScopeInterceptor"/>

  19. <interceptorname ="servlet-config"class="org.apache.struts2.interceptor.ServletConfigInterceptor"/>

  20. <interceptorname ="sessionAutowiring"class="org.apache.struts2.spring.interceptor.SessionContextAutowiringInterceptor"/>

  21. <interceptorname ="timer"class="com.opensymphony.xwork2.interceptor.TimerInterceptor"/>

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

  23. <interceptorname ="token-session"class="org.apache.struts2.interceptor.TokenSessionStoreInterceptor"/>

  24. <interceptorname ="validation"class="com.opensymphony.xwork2.validator.ValidationInterceptor"/>

  25. <interceptorname ="workflow"class="com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor"/>

  26. <interceptorname ="store"class="org.apache.struts2.interceptor.MessageStoreInterceptor"/>

  27. <interceptorname ="checkbox"class="org.apache.struts2.interceptor.CheckboxInterceptor"/>

  28. <interceptorname ="profiling"class="org.apache.struts2.interceptor.ProfilingActivationInterceptor"/>



       每個攔截器的定義包含了一個唯一的名字和攔截器類的全名(具體包名和類名)。

       在struts-default.xm中已經配置了以上的攔截器。如果您想要使用上述攔截器,只需要在應用程序struts.xml文件中通過“<include file="struts-default.xml" />”將struts-default.xml文件包含進來,並繼承其中的struts-default包(package),最後在定義Action時,使用“<interceptor-ref name="xx" />”引用攔截器或攔截器棧(interceptor stack)。一旦您繼承了struts-default包(package),所有Action都會調用攔截器棧——defaultStack。當然,在Action配置中加入“<interceptor-refname="xx" />”可以覆蓋defaultStack。

注:一旦在action中聲明瞭任何一個攔截器,就得聲明所有這個action要引用的攔截器,因爲默認攔截器已經被覆蓋了。

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

攔截器

名字

說明

Alias Interceptor

alias

在不同請求之間將請求參數在不同名字件轉換,請求內容不變

Chaining Interceptor

chain

讓前一個Action的屬性可以被後一個Action訪問,現在和chain類型的result(<result type=”chain”>)結合使用。

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>中的<param>中的內容設置到對應的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

        攔截器棧組織了一系類攔截器,例如,Struts 2 定義了一個名位basicStack的攔截器棧:

Xml代碼  收藏代碼
  1. <interceptor-stackname="basicStack">

  2. <interceptor-refname="exception"/>

  3. <interceptor-refname="servletConfig"/>

  4. <interceptor-refname="prepare"/>

  5. <interceptor-refname="checkbox"/>

  6. <interceptor-refname="params"/>

  7. <interceptor-refname="conversionError"/>

  8. </interceptor-stack>


       <interceptor-ref>是用來引用特定的攔截器或攔截器棧。

       在validationWorkflowStack的定義中就引用了攔截器棧basicStack。


Xml代碼  收藏代碼
  1. <interceptor-stackname="validationWorkflowStack">

  2. <interceptor-refname="basicStack"/>

  3. <interceptor-refname="validation"/>

  4. <interceptor-refname="workflow"/>

  5. </interceptor-stack>




2 攔截器的配置

       攔截器可以通過<param>元素來配置參數。例如,我們可以看到validation的驗證可以跳過某一個action的input()方法(對input()方法不執行驗證)。配置如下:

Xml代碼  收藏代碼
  1. <interceptor-stackname="validationWorkflowStack">

  2.    ...    

  3. <interceptor-refname="validation">

  4. <paramname="excludeMethods">

  5.            input,back,cancel,browse    

  6. </param>

  7. </interceptor-ref>

  8.    ...    


       這是因爲validation攔截器是MethodFilterInterceptor的子類,MethodFilterInterceptor定義了一個excludeMethods的參數(還有includeMethods參數)。這個參數是以逗號分隔符解析出一系列不進行攔截的方法名的。以上的配置就是對input,back,cancel,browse等方法不進行攔截驗證。

       假設已經定義了一個攔截器棧defaultStack並且該攔截器棧包含了validation攔截器,而且我們有一個action要用到defaultStack攔截器棧,但是它有一個方法doNotValidate()不需要進行validation驗證,怎麼辦呢?

       也許你會這樣配置:


Xml代碼  收藏代碼
  1. <actionname="errorConfiguration"class="com.stuqbx.web.action.ErrorAction">

  2. <interceptor-refname="validation">

  3. <paramname="excludeMethods">

  4.            input,back,cancel,browse,doNotValidate    

  5. </param>

  6. </interceptor-ref>

  7. </action>


       但是,這樣配置運行之後,會發現其他的攔截器不起作用了,如前面所說的,action中一旦聲明瞭攔截器,就得把要用到 攔截器都聲明瞭。爲此,可能要把defaultStack中所有的攔截器都在聲明一遍,這太麻煩了。其實,我們還可以這樣:

Xml代碼  收藏代碼
  1. <actionname="correctConfiguration"class="com.stuqbx.web.action.CorrectAction">

  2. <interceptor-refname="defaultStack">

  3. <paramname="validation.excludeMethods">

  4.            input,back,cancel,browse,doNotValidate    

  5. </param>

  6. </interceptor-ref>

  7. </action>


       這配置了一個action,該action用到了defaultStack攔截器棧,並且爲其中的validation攔截器的excludeMethods參數配置了相應的值。配置的語法很簡單,用interceptorName.parameterName作爲param的name。還有如果在action中用到了一個攔截器棧,這個攔截器棧中又引用了多個攔截器棧,也可以爲其中的某些攔截器配置相應的參數,語法爲:stackName.interceptorName.parameterName。


3 默認攔截器

       在package中可以用<default-interceptor-ref>來定義默認的攔截器。例如,在struts-default包中就定義了默認的攔截器:

Xml代碼  收藏代碼
  1. <packagename="struts-default"abstract="true">

  2. <!-- ... -->

  3. <default-interceptor-refname="defaultStack"/>

  4. </package>

4 攔截器工作原理

       所有的Struts 2的攔截器都直接或間接實現接口com.opensymphony.xwork2.interceptor.Interceptor。該接口提供了三個方法:

void init(); 在該攔截器被初始化之後,在該攔截器執行攔截之前,系統回調該方法。對於每個攔截器而言,此方法只執行一次。

void destroy();該方法跟init()方法對應。在攔截器實例被銷燬之前,系統將回調該方法。

String intercept(ActionInvocation invocation) throws Exception; 該方法是用戶需要實現的攔截動作。該方法會返回一個字符串作爲邏輯視圖。

       除此之外,繼承類com.opensymphony.xwork2.interceptor.AbstractInterceptor是更簡單的一種實現攔截器類的方式,因爲此類提供了init()和destroy()方法的空實現,這樣我們只需要實現intercept方法。

       有些攔截器處理是跟action的調用無關的,有些攔截器只有在action實現了某些特定的接口時才執行。ActionInvocation有一個action的屬性,存儲了被調用的action的了實例。通過用instanceof檢查是被調用的action是哪一個,攔截器就可以決定是否攔截處理。

        在自定義攔截器時,攔截器必須是無狀態的,不要使用在API提供的ActionInvocation之外的任何東西。攔截器是無狀態的是因爲Struts 2不能保證爲每一個請求或者action創建一個攔截器的實例,所以如果攔截器帶有狀態,會引發併發問題。





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章