Struts 2 攔截器之攔截器的使用

jopen 8年前發布 | 9K 次閱讀 Struts2 Web框架

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

         一、實現攔截器類

          雖然Struts 2框架提供了許多攔截器,這些攔截器也實現了Struts 2的大部分功能。但是用戶仍然可以開發自己的攔截器。

          實現自己的攔截器,應該實現com.opensymphoney.xwork2.interceptor.Interceptor接口

          該接口包含三個方法:init() destroy()interceptor(ActionInvocation invocation)

          init():在該攔截器被實例化之后,在該攔截器執行攔截之前,系統將會回調該方法。該方法主要用于初始化資源。對于每一個攔截器而言,其init()方法只會執行一次。        

          destroy():該方法在攔截器實例被銷毀之前被系統回調。該方法用于銷毀init()方法里打開的資源  

          interceptor(ActionInvocation invocation):該方法是用戶需要實現的攔截動作。該方法會返回一個字符串,系統將會跳轉到該邏輯視圖對應的實際視圖資源,不會調用被攔截的Action

          Struts 2還提供了一個AbstractInterceptor類,該類提供了一個initdestroy方法的空實現,如果我們實現的攔截器不需要打開資源,則可以無須實現這兩個方法。由此可見,繼承AbstractInterceptor類來實現自定義攔截器會更加簡單。

          下面實現一個簡單的攔截器:

public class SimpleInterceptor extends AbstractInterceptor {
    // 簡單攔截器的名字
    private String name;

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String intercept(ActionInvocation invocation) throws Exception {
        //取得被攔截的Action實例
        LoginAction action = (LoginAction) invocation.getAction();
        //打印執行開始的實現
        System.out.println(name+"攔截器的動作----------開始執行登錄Action的時間:"+new Date());
        //取得開始執行Action的時間
        long start = System.currentTimeMillis();
        //執行該攔截器的后一個攔截器
        //如果該攔截器沒有其他攔截器,則直接執行Action的execute方法
        String result = invocation.invoke();
        //打印執行結束的時間
        System.out.println(name+"攔截器的動作----------執行完登錄Action的時間:"+new Date());
        long end = System.currentTimeMillis();
        System.out.println(name+"攔截器的動作----------執行完該Action的事件為:"+(end-start)+"毫秒");

        return result;
    }
}


         當我們實現interceptor方法時,可以獲得ActionInvocation參數,這個參數可以獲得被攔截的Action實例,一旦取得了Action實例,幾乎獲得了全部的控制權。

 

         二、使用攔截器

         實現了攔截器類后,就是配置攔截器,使用攔截器。使用攔截器需要以下兩個步驟:

            1、通過<interceptor.../>元素來定義攔截器。

            2、通過<interceptor-ref.../>元素來使用攔截器。 

         攔截器的配置如下:

<package name="mystruts" extends="struts-default">
        <!-- 應用所需使用的攔截器都在改元素下配置 -->
        <interceptors>
            <!-- 配置沒有simple攔截器 -->
            <interceptor name="mysimple" class="com.app.interceptor.SimpleInterceptor">
                <!-- 為該攔截器指定參數值 -->
                <param name="name">簡單攔截器</param>
            </interceptor>
        </interceptors>

        <action name="login" class="com.app.action.LoginAction">
            <result name="error">/error.jsp</result>
            <result name="success">/welcome.jsp</result>
            <!-- 配置系統的默認攔截器 -->
            <interceptor-ref name="defaultStack"></interceptor-ref>
            <!-- 應用自定義的mysimple攔截器 -->
            <interceptor-ref name="mysimple">
                <param name="name">改名后的攔截器</param>
            </interceptor-ref>
        </action>
    </package>

         這個攔截器只是一個簡單地在控制臺打印一些文本,獲取被攔截方法的執行時間信息。

         當瀏覽者在瀏覽器中對該Action發送請求時,該攔截器將會攔截該Actionexecute方法,將會在控制臺看到如下結果:


         三、攔截方法的攔截器

         在默認情況下,如果我們為某個Action定義了攔截器,則這個攔截器會攔截該Action內所有方法,但是有時我們不需要攔截所有方法,只需要攔截指定的方法。此時需要使用Struts 2攔截器的方法過濾特性。

         為了實現方法的過濾的特性,Struts 2提供了一個MethodFilterInterceptor類,該類是AbstractInterceptor類的子類如果用戶需要自己實現的攔截器支持方法過濾特性,則應該繼承MethodFilterInterceptor。并且需要重寫doIntercept(ActionInvocation invocation)方法。

         實際上實現方法過濾的攔截器與實現普通攔截器并沒沒什么區別。所以這里就不展示代碼了。

         MethodFilterInterceptor類中,增加了如下兩個方法:

         1、public void setExcludeMethods(String excludeMethods):排除需要過濾的方法,所有在  excludeMethods字符串中列出的方法都不會被攔截

         2、public void setIncludeMethods(String includeMethods):設置需要過濾的方法,所有在includeMethods字符串中列出的方法都會被攔截。

         注:如果一個方法同時在excludeMethodsincludeMethods中列出,則該方法會被攔截。

         通過上面兩個方法,我們可以在配置文件中指定需要被攔截,或者不被攔截的方法。

         如下:

<interceptor-ref name="myfilter">
                <!-- 指定execute方法不需要被攔截 -->
                <param name="excludeMethods">execute</param>
                <!-- 指定login方法需要被攔截 -->
                <param name="includeMethods">login</param>
            </interceptor-ref>

         如果需要同時指定多個方法不需要被攔截器攔截,則多個方法之間以英文逗號隔開

         如下:

<interceptor-ref name="myfilter">
                <!-- 指定execute方法和login方法不需要被攔截 -->
                <param name="excludeMethods">execute,login</param>
            </interceptor-ref>

         如果excludeMethods參數和includeMethods參數同時知道指定了一個方法名,則該方法會被攔截器攔截。

         如下:

<interceptor-ref name="myfilter">
                <!-- 指定execute方法和login方法不需要被攔擊 -->
                <param name="excludeMethods">execute,login</param>
                <!-- 指定login方法需要被攔截 -->
                <param name="includeMethods">login</param>
            </interceptor-ref>

         上面的配置中通過excludeMethods參數指定executelogin方法不需要被攔截,includeMethods參數指定login方法需要被攔截,則攔截器會攔截login方法。

         

         四、攔截器的執行順序

         隨著系統中配置攔截器的順序不同,系統執行攔截器的順序也會不同。通常認為:先配置的攔截器,會先獲得執行機會,但是有時候也會存在一些特殊的情況。

         有如下的配置文件:

<package name="mystruts" extends="struts-default">
        <!-- 應用所需使用的攔截器都在改元素下配置 -->
        <interceptors>
            <!-- 配置沒有simple攔截器 -->
            <interceptor name="mysimple" class="com.app.interceptor.SimpleInterceptor">
                <!-- 為該攔截器指定參數值 -->
                <param name="name">簡單攔截器</param>
            </interceptor>
        </interceptors>

        <action name="login" class="com.app.action.LoginAction">
            <result name="error">/error.jsp</result>
            <result name="success">/welcome.jsp</result>
            <!-- 配置系統的默認攔截器 -->
            <interceptor-ref name="defaultStack"></interceptor-ref>
            <!-- 應用自定義的mysimple攔截器 -->
            <interceptor-ref name="mysimple">
                <param name="name">第一個</param>
            </interceptor-ref>
            <interceptor-ref name="mysimple">
                <param name="name">第二個</param>
            </interceptor-ref>
        </action>
    </package>

         通過上面的配置文件中我們可以看到,對于上面的名為loginAction,有兩次使用了mysimple攔截器攔截該Action。兩個攔截器名分別為:第一個、第二個。

         當用戶再瀏覽器中向該Action發送請求時,就會看到如下效果:



         從上面的效果中可以看到,對于在execute方法之前的動作,第一個攔截器會先起作用,也就是說配置在前面的攔截器會先起作用;對于在execute方法之后的動作,則第二個攔截器先起作用,也就是說,配置在后的攔截器會先起作用。

         所有可以得到如下結論:在Action的控制方法執行之前,位于攔截器鏈前面的攔截器會先起作用。在Action控制方法執行之后,位于攔截器鏈后面的攔截器會先起作用。



 讀李剛《輕量級Java EE企業應用實戰》

來自: http://blog.csdn.net/chenssy/article/details/7354645

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!