Struts2的攔截器(Interceptor)


 什么是攔截器。

    Interceptor(以下譯為攔截器)是Struts 2的一個強有力的工具,有許多功能(feature)都是構建於它之上,如國際化、校驗等。

    攔截器,在AOP(Aspect-Oriented Programming)中用於在某個方法或字段被訪問之前,進行攔截然后在之前或之后加入某些操作。攔截是AOP的一種實現策略。在Webwork的中文文檔的解釋為——攔截器是動態攔截Action調用的對象。它提供了一種機制可以使開發者可以定義在一個action執行的前后執行的代碼,也可以在一個action執行前阻止其執行。同時也是提供了一種可以提取action中可重用的部分的方式。

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

    

實現原理

Struts 2的攔截器實現相對簡單。當請求到達Struts 2的ServletDispatcher時,Struts 2會查找配置文件,並根據其配置實例化相對的攔截器對象,然后串成一個列表(list),最后一個一個地調用列表中的攔截器,如圖1所示。

圖1 攔截器調用序列圖
圖1 攔截器調用序列圖

STRUTS2內建攔截器

Struts 2已經為您提供豐富多樣的,功能齊全的攔截器實現。大家可以到struts2-all-2.0.1.jar或struts2-core-2.0.1.jar包的struts-default.xml查看關於默認的攔截器與攔截器鏈的配置。

以下部分就是從struts-default.xml文件摘取的內容:

< interceptor name ="alias" class ="com.opensymphony.xwork2.interceptor.AliasInterceptor" />
< interceptor name ="autowiring" class ="com.opensymphony.xwork2.spring.interceptor.ActionAutowiringInterceptor" />
< interceptor name ="chain" class ="com.opensymphony.xwork2.interceptor.ChainingInterceptor" />
< interceptor name ="conversionError" class ="org.apache.struts2.interceptor.StrutsConversionErrorInterceptor" />
< interceptor name ="createSession" class ="org.apache.struts2.interceptor.CreateSessionInterceptor" />
< interceptor name ="debugging" class ="org.apache.struts2.interceptor.debugging.DebuggingInterceptor" />
< interceptor name ="external-ref" class ="com.opensymphony.xwork2.interceptor.ExternalReferencesInterceptor" />
< interceptor name ="execAndWait" class ="org.apache.struts2.interceptor.ExecuteAndWaitInterceptor" />
< interceptor name ="exception" class ="com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor" />
< interceptor name ="fileUpload" class ="org.apache.struts2.interceptor.FileUploadInterceptor" />
< interceptor name ="i18n" class ="com.opensymphony.xwork2.interceptor.I18nInterceptor" />
< interceptor name ="logger" class ="com.opensymphony.xwork2.interceptor.LoggingInterceptor" />
< interceptor name ="model-driven" class ="com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor" />
< interceptor name ="scoped-model-driven" class ="com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor" />
< interceptor name ="params" class ="com.opensymphony.xwork2.interceptor.ParametersInterceptor" />
< interceptor name ="prepare" class ="com.opensymphony.xwork2.interceptor.PrepareInterceptor" />
< interceptor name ="static-params" class ="com.opensymphony.xwork2.interceptor.StaticParametersInterceptor" />
< interceptor name ="scope" class ="org.apache.struts2.interceptor.ScopeInterceptor" />
< interceptor name ="servlet-config" class ="org.apache.struts2.interceptor.ServletConfigInterceptor" />
< interceptor name ="sessionAutowiring" class ="org.apache.struts2.spring.interceptor.SessionContextAutowiringInterceptor" />
< interceptor name ="timer" class ="com.opensymphony.xwork2.interceptor.TimerInterceptor" />
< interceptor name ="token" class ="org.apache.struts2.interceptor.TokenInterceptor" />
< interceptor name ="token-session" class ="org.apache.struts2.interceptor.TokenSessionStoreInterceptor" />
< interceptor name ="validation" class ="com.opensymphony.xwork2.validator.ValidationInterceptor" />
< interceptor name ="workflow" class ="com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor" />
< interceptor name ="store" class ="org.apache.struts2.interceptor.MessageStoreInterceptor" />
< interceptor name ="checkbox" class ="org.apache.struts2.interceptor.CheckboxInterceptor" />
< interceptor name ="profiling" class ="org.apache.struts2.interceptor.ProfilingActivationInterceptor" />

 工具攔截器

    首先,我們先看一些公具攔截器。這些攔截器提供了輔助看法,調優以及解決問題的簡單工具。

           1.timer攔截器

              這個簡單的攔截器只記錄執行花費的時間。在攔截器棧中的位置決定了它實際測量了什么時間。

          2.logger攔截器

              這個攔截器提供了一個簡單的日志記錄,記錄了在預處理時的進入聲明,以及在后加工時的退出聲明。

數據轉移攔截器

           攔截器能夠用來處理數據轉移,通過攔截器可以將數據轉移到動作上,例如從XML配置文件中的定義的參數。

           1.param攔截器

             他將請求參數轉移到通過valuestack公開的屬性上,攔截器不知道這些數據終究去到哪里,它只是把數據轉移到valuestack上一個匹配的屬性上。

           2.static-param攔截器

             它的作用和param攔截器的作用相似,不同的是參數的來源,這個攔截器轉移的參數定義在聲明性架構的動作元素中。

           3.servlet-config攔截器

             這個攔截器通過各種對象設置到動作必須實現的接口。

           4.fileupload攔截器

             fileupload攔截器將文件和元數據從多重請求轉換為常規的請求參數,以便能夠將他們像普通參數一樣設置到動作上。

            struts的內建攔截器還有很多,比如workflow攔截器,validation攔截器等等,由於篇幅有限這里就不詳細介紹了,如果大家有興趣可以查閱相關資糧,比如struts2 in action 這里介紹的都很詳細,只是書翻譯的比較爛,下面開始介紹我的自定義攔截器。

自定義攔截器

             在將自定義攔截器之前,讓我們先了解一下,怎么將攔截器映射到組件上。可以使用interceptor-ref 元素完成攔截器和動作的關聯。

             構建自定義攔截器首先要讓自己的類實現一個interceptor接口,實現這個幾口要覆寫這個類的方法:

             public String intercept(ActionInvocation actioninvocation) throws Exception {}

             如果我們自定義的方法,如果想要設置和覆蓋攔截器的參數:

      <interceptor-ref name="authenticationInterceptor" >
                    <param name = "excludeMethods">login,register</param>
                </interceptor-ref>

            就必須繼承MethodFilterInterceptor類,我因為這個問題浪費了我好幾個小時,才把這個問題解決,具體的攔截器類實現如下:

      @Override
            protected String doIntercept(ActionInvocation actioninvocation)
                  throws Exception {
                Map session = actioninvocation.getInvocationContext().getSession();
                UserDomain user = (UserDomain) session.get("user");
                    if (user == null) {
                        return Action.LOGIN;
                    } else {
                      Action action = (Action) actioninvocation.getAction();
                            if (action instanceof UserAware) {
                                ((UserAware) action).setUser(user);
                        }
                       System.out.println("Logged in: interceptor");
                       return actioninvocation.invoke();
                }
            }

     引入的struts.xml文件如下:
        <interceptors>
            <interceptor name="authenticationInterceptor"
                class="com.duqiao.interceptor.AuthenticationInterceptor" />

            <interceptor-stack name="duqiaoStack">
                <interceptor-ref name="authenticationInterceptor" >
                    <param name = "excludeMethods">login,register</param>
                </interceptor-ref>
                <interceptor-ref name="defaultStack" />
            </interceptor-stack>

        </interceptors>

        <default-interceptor-ref name="duqiaoStack" />
    本文部分內容引自“http://www.blogjava.net/max/archive/2006/12/06/85925.html”。max on java

           

 

           


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM