Struts2攔截器的使用 (詳解)

如何使用struts2攔截器,或者自定義攔截器。特別注意,在使用攔截器的時候,在Action裏面必須最後必定要引用struts2自帶的攔截器缺省堆棧defaultStack,以下(這裏我是引用了struts2自帶的checkbox攔截器):
<interceptor-ref name="checkbox">
  <param name="uncheckedValue">0</param>
</interceptor-ref>
<interceptor-ref name="defaultStack"/>(必須加,不然出錯) html

也能夠改成對全局Action設置本身須要的攔截器,以下:

在struts.xml裏面定義全局的配置設置
  <package name="struts-shop" extends="struts-default">
    <interceptors>
      <interceptor-stack name="myStack">
        <interceptor-ref name="checkbox">
          <param name="uncheckedValue">0</param>
       </interceptor-ref>
       <interceptor-ref name="defaultStack"/>
      </interceptor-stack>
    </interceptors>
    <default-interceptor-ref name="myStack"/>(這句是設置全部Action自動調用的攔截器堆棧)
  </package>
 
struts-action.xml裏面配置Action以下:
  <package name="LogonAdmin" extends="struts-shop">(這裏擴展struts.xml裏面定義的配置就能夠了)
  <action name="logon" class="logonAction">
     <result>/jsp/smeishop/admin/index.jsp</result>
     <result name="error">/jsp/smeishop/admin/logon.jsp</result>
     <result name="input">/jsp/smeishop/admin/logon.jsp</result>
   </action>
   <action name="logout" class="logoutAction">
     <result>/jsp/smeishop/admin/logon.jsp</result>
   </action>
 </package> apache

你的攔截器能夠正常工做了!!HOHO cookie

如下是參考資料 session

struts2自帶的配置及其攔截器配置 app


Struts2 攔截器 [Interceptor] jsp

攔截器的工做原理如上圖,每個Action請求都包裝在一系列的攔截器的內部。攔截器能夠在Action執行直線作類似的操做也能夠在Action執行直後作回收操做。 post

 

每個Action既能夠將操做轉交給下面的攔截器,Action也能夠直接退出操做返回客戶既定的畫面。 this

 

如何自定義一個攔截器? spa

自定義一個攔截器須要三步: debug

1 自定義一個實現Interceptor接口(或者繼承自AbstractInterceptor)的類。

2 在strutx.xml中註冊上一步中定義的攔截器。

3 在須要使用的Action中引用上述定義的攔截器,爲了方便也可將攔截器定義爲默認的攔截器,這樣在不加特殊聲明的狀況下全部的Action都被這個攔截器攔截。

 

Interceptor接口聲明瞭三個方法:

 

public interface Interceptor extends Serializable {

 

    void destroy();

 

    void init();

 

    String intercept(ActionInvocation invocation) throws Exception;

}

 

Init方法在攔截器類被建立以後,在對Action鏡像攔截以前調用,至關於一個post-constructor方法,使用這個方法能夠給攔截器類作必要的初始話操做。

 

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

 

Intercept是攔截器的主要攔截方法,若是須要調用後續的Action或者攔截器,只須要在該方法中調用invocation.invoke()方法便可,在該方法調用的先後能夠插入Action調用先後攔截器須要作的方法。若是不須要調用後續的方法,則返回一個String類型的對象便可,例如Action.SUCCESS。

另外AbstractInterceptor提供了一個簡單的Interceptor的實現,這個實現爲:

public abstract class AbstractInterceptor implements Interceptor {

 

     public void init() {

    }

   

    public void destroy() {

    }

 

 

    public abstract String intercept(ActionInvocation invocation) throws Exception;

}

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

 

咱們嘗試編寫一個Session過濾用的攔截器,該攔截器查看用戶Session中是否存在特定的屬性(LOGIN屬性)若是不存在,停止後續操做定位到LOGIN,不然執行原定操做,代碼爲:

public class CheckLoginInterceptor extends AbstractInterceptor {

    public static final String LOGIN_KEY = "LOGIN";

    public static final String LOGIN_PAGE = "global.login";

 

    public String intercept(ActionInvocation actionInvocation) throws Exception {

 

        System.out.println("begin check login interceptor!");

        // 對LoginAction不作該項攔截

        Object action = actionInvocation.getAction();

        if (action instanceof LoginAction) {

            System.out.println("exit check login, because this is login action.");

            return actionInvocation.invoke();

        }

 

        // 確認Session中是否存在LOGIN

        Map session = actionInvocation.getInvocationContext().getSession();

        String login = (String) session.get(LOGIN_KEY);

        if (login != null && login.length() > 0) {

            // 存在的狀況下進行後續操做。

            System.out.println("already login!");

            return actionInvocation.invoke();

        } else {

            // 不然終止後續操做,返回LOGIN

            System.out.println("no login, forward login page!");

            return LOGIN_PAGE;

        }

    }

}

 

註冊攔截器

<interceptors>

            <interceptor

name="login" 

class="com.jpleasure.teamware.util.CheckLoginInterceptor"/>

            <interceptor-stack name="teamwareStack">

                <interceptor-ref name="login"/>

                <interceptor-ref name="defaultStack"/>

            </interceptor-stack>

</interceptors>

 

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

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

這樣在後續同一個package內部的全部Action執行以前都會被login攔截。

 

 

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

 

攔截器

名字

說明

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

 

註冊並引用Interceptor

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

   <interceptors>

       <interceptor name="timer" class=".."/>

       <interceptor name="logger" class=".."/>

   </interceptors>

 

   <action name="login" class="tutorial.Login">

        <interceptor-ref name="timer"/>

        <interceptor-ref name="logger"/>

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

        <result name="success"

            type="redirect-action">/secure/home</result>

   </action>

</package>

 

能夠將多個攔截器合併在一塊兒做爲一個堆棧調用,當一個攔截器堆棧被附加到一個Action的時候,要想Action執行,必須執行攔截器堆棧中的每個攔截器。

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

   <interceptors>

        <interceptor name="timer" class=".."/>

        <interceptor name="logger" class=".."/>

        <interceptor-stack name="myStack">

           <interceptor-ref name="timer"/>

           <interceptor-ref name="logger"/>

        </interceptor-stack>

    </interceptors>

 

    <action name="login" class="tutuorial.Login">

         <interceptor-ref name="myStack"/>

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

         <result name="success"

             type="redirect-action">/secure/home</result>

    </action>

</package>

 

上述說明的攔截器在默認的Struts2應用中,根據慣例配置了若干個攔截器堆棧,詳細情參看struts-default.xml

其中有一個攔截器堆棧比較特殊,他會應用在默認的每個Action上。

<interceptor-stack name="defaultStack">

    <interceptor-ref name="exception"/>

    <interceptor-ref name="alias"/>

    <interceptor-ref name="servletConfig"/>

    <interceptor-ref name="prepare"/>

    <interceptor-ref name="i18n"/>

    <interceptor-ref name="chain"/>

    <interceptor-ref name="debugging"/>

    <interceptor-ref name="profiling"/>

    <interceptor-ref name="scopedModelDriven"/>

    <interceptor-ref name="modelDriven"/>

    <interceptor-ref name="fileUpload"/>

    <interceptor-ref name="checkbox"/>

    <interceptor-ref name="staticParams"/>

    <interceptor-ref name="params">

      <param name="excludeParams">dojo"..*</param>

    </interceptor-ref>

    <interceptor-ref name="conversionError"/>

    <interceptor-ref name="validation">

        <param name="excludeMethods">input,back,cancel,browse</param>

    </interceptor-ref>

    <interceptor-ref name="workflow">

        <param name="excludeMethods">input,back,cancel,browse</param>

    </interceptor-ref>

</interceptor-stack>

 

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

<interceptor-ref name="validation">

 <param name="excludeMethods">myValidationExcudeMethod</param>

</interceptor-ref>

<interceptor-ref name="workflow">

 <param name="excludeMethods">myWorkflowExcludeMethod</param>

</interceptor-ref>

或者

<interceptor-ref name="defaultStack">

    <param name="validation.excludeMethods">myValidationExcludeMethod</param>

    <param name="workflow.excludeMethods">myWorkflowExcludeMethod</param>

</interceptor-ref>

 

每個攔截器都有兩個默認的參數:

excludeMethods - 過濾掉不使用攔截器的方法和

includeMethods – 使用攔截器的方法。

 

須要說明的幾點:

1 攔截器執行的順序按照定義的順序執行,例如:

<interceptor-stack name="xaStack">

 <interceptor-ref name="thisWillRunFirstInterceptor"/>

 <interceptor-ref name="thisWillRunNextInterceptor"/>

 <interceptor-ref name="followedByThisInterceptor"/>

 <interceptor-ref name="thisWillRunLastInterceptor"/>

</interceptor-stack>

的執行順序爲:

thisWillRunFirstInterceptor

 thisWillRunNextInterceptor

    followedByThisInterceptor

      thisWillRunLastInterceptor

        MyAction1

        MyAction2 (chain)

        MyPreResultListener

        MyResult (result)

      thisWillRunLastInterceptor

    followedByThisInterceptor

 thisWillRunNextInterceptor

thisWillRunFirstInterceptor

 

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

<action name="login" class="tutorial.Login">

     <interceptor-ref name="timer"/>

     <interceptor-ref name="logger"/>

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

 

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

     <result type="redirect-action">/secure/home</result>

</action>

能夠按照以下的方式定義:

<interceptors>

     <interceptor-stack name="myStack">

        <interceptor-ref name="timer"/>

        <interceptor-ref name="logger"/>

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

     </interceptor-stack>

</interceptors>

 

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

 

<action name="login" class="tutorial.Login">

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

       <result type="redirect-action">/secure/home</result>

</action>

 

3 如何訪問HttpServletRequest,HttpServletResponse或者HttpSession

有兩種方法能夠達到效果,使用ActionContext

Map attibutes = ActionContext.getContext().getSession();

或者實現相應的接口:

HttpSession            SessionAware

HttpServletRequest     ServletRequestAware

HttpServletResponse    ServletResponseAware

相關文章
相關標籤/搜索