Struts2攔截器(Interceptor)

++YONG原創,轉載請註明

1.    理解攔截器

1.1.    什麼是攔截器:

攔截器,在AOPAspect-Oriented Programming)中用於在某個方法或字段被訪問之前,進行攔截然後在之前或之後加入某些操作。攔截是AOP的一種實現策略。

Webwork的中文文檔的解釋爲——攔截器是動態攔截Action調用的對象。它提供了一種機制可以使開發者可以定義在一個action執行的前後執行的代碼,也可以在一個action執行前阻止其執行。同時也是提供了一種可以提取action中可重用的部分的方式。

談到攔截器,還有一個詞大家應該知道——攔截器鏈(Interceptor Chain,在Struts 2中稱爲攔截器棧Interceptor Stack)。攔截器鏈就是將攔截器按一定的順序聯結成一條鏈。在訪問被攔截的方法或字段時,攔截器鏈中的攔截器就會按其之前定義的順序被調用。

1.2.    攔截器的實現原理:

大部分時候,攔截器方法都是通過代理的方式來調用的。Struts 2的攔截器實現相對簡單。當請求到達Struts 2ServletDispatcher時,Struts 2會查找配置文件,並根據其配置實例化相對的攔截器對象,然後串成一個列表(list),最後一個一個地調用列表中的攔截器。如下圖:

2.    攔截器的配置

Struts 2已經爲您提供豐富多樣的,功能齊全的攔截器實現。大家可以至struts2jar包內的struts-default.xml查看關於默認的攔截器與攔截器鏈的配置。

Struts2XWork)提供的攔截器的功能說明:

 

攔截器

名字

說明

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調用ActionsetModel方法將其放入Action內部。

Parameters Interceptor

params

將請求中的參數設置到Action中去。

Prepare Interceptor

prepare

如果Acton實現了Preparable,則該攔截器調用Action類的prepare方法。

Scope Interceptor

scope

Action狀態存入sessionapplication的簡單方法。

Servlet Config Interceptor

servletConfig

提供訪問HttpServletRequestHttpServletResponse的方法,以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

調用Actionvalidate方法,一旦有錯誤返回,重新定位到INPUT畫面

Parameter Filter Interceptor

N/A

從參數列表中刪除不必要的參數

Profiling Interceptor

profiling

通過參數激活profile

 

       struts.xml文件中定義攔截器,攔截器棧:

<package name="my" extends="struts-default" namespace="/manage">

        <interceptors>

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

        <interceptor name="攔截器名" class="攔截器實現類"/>

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

        <interceptor-stack name="攔截器棧名">

             <interceptor-ref name="攔截器一"/>

             <interceptor-ref name="攔截器二"/>

        </interceptor-stack>

        </interceptors>

        ......

</package>

3.    使用攔截器

一旦定義了攔截器和攔截器棧後,就可以使用這個攔截器或攔截器棧來攔截Action了。攔截器的攔截行爲將會在Actionexceute方法執行之前被執行。

<action name="userOpt" class="org.qiujy.web.struts2.action.UserAction">

            <result name="success">/success.jsp</result>

            <result name="error">/error.jsp</result>

<!-- 使用攔截器,一般配置在result之後, -->

<!-- 引用系統默認的攔截器 -->

<interceptor-ref name="defaultStack"/>

            <interceptor-ref name="攔截器名或攔截器棧名"/>

        </action>

       此處需要注意的是,如果爲Action指定了一個攔截器,則系統默認的攔截器棧將會失去作用。爲了繼續使用默認攔截器,所以上面配置文件中手動引入了默認攔截器。

4.    自定義攔截器

作爲“框架(framework)”,可擴展性是不可或缺的。雖然,Struts 2爲我們提供如此豐富的攔截器實現,但是這並不意味我們失去創建自定義攔截器的能力,恰恰相反,在Struts 2自定義攔截器是相當容易的一件事。

 

 

 

 

4.1.    實現攔截器類:

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

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

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

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

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

4.2.    使用自定義攔截器:

兩個步驟:

l  通過<interceptor …>元素來定義攔截器。

l  通過<interceptor-ref …>元素來使用攔截器。

5.    自定義攔截器示例

5.1.    問題描述:

使用自定義攔截器來完成用戶權限的控制:當瀏覽者需要請求執行某個操作時,應用需要先檢查瀏覽者是否登錄,以及是否有足夠的權限來執行該操作。

5.2.    實現權限控制攔截器類:

AuthorizationInterceptor.java

package org.qiujy.common;

 

import java.util.Map;

 

import com.opensymphony.xwork2.Action;

import com.opensymphony.xwork2.ActionInvocation;

import com.opensymphony.xwork2.interceptor.AbstractInterceptor;

 

/**

 * 權限檢查攔截器

 *

 * @author qiujy

 * @version 1.0

 */

public class AuthorizationInterceptor extends AbstractInterceptor {

 

    /*

     * 攔截Action處理的攔截方法

     *

     */

    public String intercept(ActionInvocation invocation) throws Exception {

       

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

        String userName = (String) session.get("userName");

       

        if (null != userName && userName.equals("test")) {

            System.out.println("攔截器:合法用戶登錄---");

            return invocation.invoke();

        } else {

            System.out.println("攔截器:用戶未登錄---");

            return Action.LOGIN;

        }

    }

}

 

5.3.    配置權限控制攔截器:

struts.xml

<!DOCTYPE struts PUBLIC

        "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"

        "http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>

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

       

        <interceptors>

        <!-- 定義權限控制攔截器 -->

        <interceptor name="authority" class="org.qiujy.common.AuthorizationInterceptor"/>

        </interceptors>

       

        <!-- 定義全局處理結果 -->

        <global-results>

        <!-- 邏輯名爲login的結果,映射到/login.jsp頁面 -->

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

        </global-results>

       

        <action name="listall" class="org.qiujy.web.struts2.action.UserAction" method="listAllUser">

            <result name="success">/listall.jsp</result>

            <!-- 使用攔截器 -->

            <interceptor-ref name="defaultStack"/>

            <interceptor-ref name="authority"/>

        </action>

       

        <action name="userOpt" class="org.qiujy.web.struts2.action.UserAction">

            <result name="success">/success.jsp</result>

        </action>

    </package>

</struts>

       其它頁面見源代碼。

5.4.    運行調試:

在瀏覽器地址欄直接輸入http://localhost:8080/AuthorityInterceptorDemo/listall.action 來訪問,此動作配置了權限攔截器,所有被轉到登錄頁面。

登錄後:

再訪問http://localhost:8080/AuthorityInterceptorDemo/listall.action 這個鏈接:

如果爲了簡化struts.xml文件的配置,避免在每個Action重複配置該攔截器,可以將攔截器配置成了一個默認攔截器棧。如下:

<!DOCTYPE struts PUBLIC

        "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"

        "http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>

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

 

        <interceptors>

            <!-- 定義權限控制攔截器 -->

            <interceptor name="authority"

                class="org.qiujy.common.AuthorizationInterceptor" />

            <!-- 定義一個包含權限控制的攔截器棧 -->

            <interceptor-stack name="mydefault">

                <interceptor-ref name="defaultStack" />

                <interceptor-ref name="authority" />

            </interceptor-stack>

        </interceptors>

       

        <!-- 定義默認攔截器 -->

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

 

        <!-- 定義全局處理結果 -->

        <global-results>

            <!-- 邏輯名爲login的結果,映射到/login.jsp頁面 -->

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

        </global-results>

 

        <action name="listall"

            class="org.qiujy.web.struts2.action.UserAction"

            method="listAllUser">

            <result name="success">/listall.jsp</result>

        </action>

    </package>

   

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

        <action name="userOpt" class="org.qiujy.web.struts2.action.UserAction">

            <result name="success">/success.jsp</result>

        </action>

    </package>

</struts>

一旦在某個包下定義了默認攔截器棧,在該包下的所有action都會使用此攔截器棧。對於那些不想使用些攔截器棧的action,則應該將它放置在其它的包下

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