<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    JAVA & XML & JAVASCRIPT & AJAX & CSS

    Web 2.0 技術儲備............

      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
      77 隨筆 :: 17 文章 :: 116 評論 :: 0 Trackbacks

    轉自(http://samyulong.javaeye.com/blog/217092)

    一、什么是攔截器?

    提到攔截器,使我不得不 想起武俠劇中劫匪們常說的一句話:“此山是我開,此樹是我栽,要打此路過,留下買路財!”。難不成程序中也有“打劫”的,說的沒錯,攔截器就是個打劫的。 在現實生活中,劫匪劫的大都是錢財,當然也有別的什么,那么程序中的“劫匪”劫的又是什么呢?或者說程序中為什么需要它?在我們的日常編程中少不了寫一些 重復的代碼,例如在一個地方中寫了一段代碼,后來發現這段代碼在其它地方中同樣需要,在傳統的編程中我們一定會采取復制、粘貼的辦法。如果這段代碼只在這 一兩個處需要,我們采取這種辦法,還說的過去,但是如果系統對這段代碼過于依賴,也就是這段代碼在系統中出現的過多,如果那一天我們發現這段代碼中在某些 地方還需要完善,我們是不是要著個修改它們呢?我估計沒有人會這么做,它嚴重違反了軟件開發中一條非常重要的DRY規則,不寫重復代碼。說了這么多你一定知道我們為什么需要在程序中弄一個“劫匪”了吧。這個“劫匪”就是并不是劫取什么東西,只是為了在某個程序執行前后,動態的增加一些功能(以前所寫通用代碼塊)或進行一些檢查工作。那么這個攔截器到底是怎么實現的呢?實際上它是用Java中的動態代理來實現的。

    二、攔截器在Struts2中的應用

    對于Struts2框架而言,正是大量的內置攔截器完成了大部分操作。像params攔截器將http請求中參數解析出來賦值給Action中對應的屬性。Servlet-config攔截器負責把請求中HttpServletRequest實例和HttpServletResponse實例傳遞給Action……struts2內置的攔截器有很多,在此我就不一一列舉了

    那么怎么在struts2中定義自己的攔截器呢?

        很簡單Struts2為我們提供了一個Interceptor接口,該接口源代碼如下:

    publicinterface Interceptor extends Serializable {

        void destroy();

        void init();

        String intercept(ActionInvocation invocation) throws Exception;

    }

    1)    init():在攔截器執行之前調用,主要用于初始化系統資源。

    2)    destroty():init()對應,用于攔截器執行之后銷毀資源。

    3)    intercept():攔截器的核心方法,實現具體的攔截操作。與action一樣,該方法也返回一個字符串作為邏輯視圖。如果攔截器成功調用了action,則返回一個真正的,也就是該actionexecute()方法返回的邏輯視圖,反之,則返回一個自定義的邏輯視圖。

    通常我們使用攔截器并不需要申請資源,為此Struts2還為我們提供了一個AbstractInterceptor類,該類的init()destroy()都是空實現。我們開發自己的攔截器只需要繼承這個類就行了。

        下面創建一個判斷用戶是否登錄的攔截器。代碼如下:
             

    import java.util.Map;
    import com.opensymphony.xwork2.Action;
    import com.opensymphony.xwork2.ActionInvocation;
    import com.opensymphony.xwork2.interceptor.AbstractInterceptor;

    @SuppressWarnings(
    "serial")
    public class CheckLoginInterceptor extends AbstractInterceptor {

        @SuppressWarnings(
    "unchecked")
        
    public String intercept(ActionInvocation actionInvocation) throws Exception {
             System.out.println(
    "begin check login interceptor!");

                
    // 檢查Session中是否存在user

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

                String username 
    = (String) session.get("user");

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

                    
    // 存在的情況下進行后續操作。

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

                    
    return actionInvocation.invoke();

                } 
    else {

                    
    // 否則終止后續操作,返回LOGIN

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

                    
    return Action.LOGIN;

                }

            }

        }
        創建好攔截器后,還不能使用,還需要我們在struts.xml中配置一下。

      下面看一下怎么配置攔截器。

    <interceptors>

               <interceptor name="checkLogin" class="com.myblog.interceptor.CheckLoginInterceptor" />

    </interceptors>

       這個定義好的攔截器在Action中怎么使用呢?使用方法很簡單,如下:

    <action name=" " class=" " >

               <result> </result>

               <interceptor-ref name="checkLogin" />

    </action>

       一旦我們為某個action引用了自定義的攔截器,struts2默認的攔截器就不會再起作用,因此還需要引用默認攔截器。

    <action name=" " class=" " >

               <result> </result>

               <interceptor-ref name="checkLogin" />

                         <interceptor-ref name="defaultStack" />

    </action>

       但是我們這么做似乎也不太方便,因為如果攔截器checkLogin需要被多個action引用的話,每一個都要配置一遍太麻煩了。我們可以把它定義成默認的攔截器。

    <interceptors>

               <interceptor name="checkLogin" class="com.myblog.interceptor.CheckLoginInterceptor" />

               <!—-定義一個攔截器棧-->

               <interceptor-stack name="mydefault">

                  <interceptor-ref name="defaultStack" />

                  <interceptor-ref name="checkLogin" />

               </interceptor-stack>

    </interceptors>

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

       另外,struts2還為我們提供了一個方法過濾的攔截器MethodFilterInterceptor類,該類繼承AbstractInterceptor類,重寫了intercept(ActionInvocation invocation)并提供了一個新的方法doInterceptor(ActionInvocation invocation)抽象方法。該類的使用方法很簡單,就不舉例了。這個攔截器與以往的攔截器配置有所不同。那就是可以指定哪些方法需要被攔截,那些不需要。通常在引用該攔截器時指定。

    <interceptor-ref name="  ">

           <param name="exculdeMethods"></param>

           <param name="includeMethods"></param>    

    </interceptor-ref>

       exculdeMethods:是不被攔截的方法,如果有多個以逗號分隔。

       includeMethods:需要被攔截的方法,如果有多個以逗號分隔。

     



        下面我來實驗下。我們寫個攔截器棧
       

    <interceptors>
       
    <interceptor name="authorize" class="com.struts2.interceptor.AuthorizeInterceptor" />
       
    <interceptor-stack name="appStack">
          
    <!-- 你自定義的 -->
          
    <interceptor-ref name="authorize"/>
          
    <!-- 系統內置的攔截器棧 -->
          
    <interceptor-ref name="defaultStack"/>
       
    </interceptor-stack>
    </interceptors>
    <action name="forward" class="com.struts2.RequestForward">
       
    <interceptor-ref name="appStack"/>
       
    <result name="index">index.jsp</result>
       
    <result name="NOT_FOUND">not_found.jsp</result>
    </action>
        恩,還是有點很迷茫的位置,比說的攔截器的調用順序是根據xml里面的順序來的嗎?還有可以指定只在action之前或者只在action之后調用嗎?說實話我也搞不清楚,在運用的過程中,大家慢慢在來體會


    攔截器幾乎完成了Struts2框架70%的工作,包括解析請求參數、將請求參數賦值給Action屬性、執行數據校驗、文件上傳……,Struts2設計的靈巧性,更大程度地得益于攔截器設計,當需要擴展Struts2功能時,只需要提供對應攔截器,并將它配置在Struts2容器中即可;如果不需要該功能時,也只需要取消該攔截器的配置即可。這種可插拔式的設計,正是軟件設計領域一直孜孜以求的目標。

    實際上,Struts2的精髓就在于攔截器,掌握了Struts2的攔截器機制,你就可以說精通了Struts2。
    從某個角度來看,我們可以把Struts2框架理解成一個空殼,而這些攔截器像一個一個抽屜,隨時可以
    插進入,也可以拔出來——這是軟件產品一直追求的目標。
    如果你喜歡,你可以把Struts2的全部插件拔出,那么Struts2就成了一個空容器——
    而這種空,正是 Struts2的魅力,你可以把任何自己想要的東西填入進去,甚至包括自己完全實現這個框架。

    另一方面,因為Struts2的插件機制,Struts2提供了無限擴展的可能性,你可以把自己想要的任何
    東西做成插件,然后填入Struts2——這樣的結果是:一個企業,一個團隊,可以把自己業務相關的東西
    做成插件,隨時隨地地復用。
    也就是說:如果你想要,你可以把Struts2改造成屬于自己的框架。

    當然,Struts2也內建了大量的攔截器,這些攔截器以name-class對的形式配置在struts-default. xml文件中,其中name是攔截器的名字,就是以后使用該攔截器的唯一標識;class則指定了該攔截器的實現類,如果我們定義的package繼承了Struts2的默認struts-default包,則可以自由使用下面定義的攔截器,否則必須自己定義這些攔截器。
    下面是Struts2內建攔截器的簡要介紹:
    alias:實現在不同請求中相似參數別名的轉換。
    autowiring:這是個自動裝配的攔截器,主要用于當Struts2和Spring整合時,Struts2可以使用自動裝配的方式來訪問Spring容器中的Bean。
    chain:構建一個Action鏈,使當前Action可以訪問前一個Action的屬性,一般和<result type="chain" .../>一起使用。
    conversionError:這是一個負責處理類型轉換錯誤的攔截器,它負責將類型轉換錯誤從ActionContext中取出,并轉換成Action的FieldError錯誤。
    createSession:該攔截器負責創建一個HttpSession對象,主要用于那些需要有HttpSession對象才能正常工作的攔截器中。
    debugging:當使用Struts2的開發模式時,這個攔截器會提供更多的調試信息。
    execAndWait:后臺執行Action,負責將等待畫面發送給用戶。
    exception:這個攔截器負責處理異常,它將異常映射為結果。
    fileUpload:這個攔截器主要用于文件上傳,它負責解析表單中文件域的內容。
    i18n:這是支持國際化的攔截器,它負責把所選的語言、區域放入用戶Session中。
    logger:這是一個負責日志記錄的攔截器,主要是輸出Action的名字。
    model-driven:這是一個用于模型驅動的攔截器,當某個Action類實現了ModelDriven接口時,它負責把getModel()方法的結果堆入ValueStack中。
    scoped-model-driven:如果一個Action實現了一個ScopedModelDriven接口,該攔截器負責從指定生存范圍中找出指定的Modol,并將通過setModel方法將該Model傳給Action實例。
    params:這是最基本的一個攔截器,它負責解析HTTP請求中的參數,并將參數值設置成Action對應的屬性值。
    prepare:如果action實現了Preparable接口,將會調用該攔截器的prepare()方法。
    static-params:這個攔截器負責將xml中<action>標簽下<param>標簽中的參數傳入action。
    scope:這是范圍轉換攔截器,它可以將Action狀態信息保存到HttpSession范圍,或者保存到ServletContext范圍內。
    servlet-config:如果某個Action需要直接訪問Servlet API,就是通過這個攔截器實現的。
    注意:盡量避免在Action中直接訪問Servlet API,這樣會導致Action與Servlet的高耦合。
    roles:這是一個JAAS(Java Authentication and Authorization Service,Java授權和認證服務)攔截器,只有當瀏覽者取得合適的授權后,才可以調用被該攔截器攔截的Action。
    timer:這個攔截器負責輸出Action的執行時間,這個攔截器在分析該Action的性能瓶頸時比較有用。
    token:這個攔截器主要用于阻止重復提交,它檢查傳到Action中的token,從而防止多次提交。
    token-session:這個攔截器的作用與前一個基本類似,只是它把token保存在HttpSession中。
    validation:通過執行在xxxAction-validation.xml中定義的校驗器,從而完成數據校驗。
    workflow:這個攔截器負責調用Action類中的validate方法,如果校驗失敗,則返回input的邏輯視圖。
    大部分時候,開發者無需手動控制這些攔截器,因為struts-default.xml文件中已經配置了這些攔截器,只要我們定義的包繼承了系統的struts-default包,就可以直接使用這些攔截器。

    當然,Struts2的攔截器機制并不是來自于Struts1,而是來自于WebWork。


    posted on 2009-03-02 11:31 Web 2.0 技術資源 閱讀(1049) 評論(0)  編輯  收藏 所屬分類: Struts2

    只有注冊用戶登錄后才能發表評論。


    網站導航:
    博客園   IT新聞   Chat2DB   C++博客   博問  
     
    主站蜘蛛池模板: 在线永久免费的视频草莓| 亚洲午夜福利精品无码| 亚洲精品人成网线在线播放va| 国产资源免费观看| 国产免费区在线观看十分钟| 久久久久久久亚洲Av无码| 黄色片在线免费观看| 国内成人精品亚洲日本语音 | 狼群影院在线观看免费观看直播| www.亚洲日本| 免费v片在线观看无遮挡| 国产精品白浆在线观看免费| 亚洲乱码日产精品一二三| 亚洲一区二区三区偷拍女厕| 国产麻豆视频免费观看| 久久国产乱子伦精品免费午夜| 亚洲人成网站日本片| 黑人大战亚洲人精品一区| 国产成人免费网站| 九九九国产精品成人免费视频| 亚洲老熟女@TubeumTV| 亚洲成a人片在线观看老师| 久久久久久精品免费免费自慰| 免费一级全黄少妇性色生活片| 亚洲视频一区在线| 亚洲爽爽一区二区三区| 欧美最猛性xxxxx免费| 国产羞羞的视频在线观看免费| 国产亚洲一卡2卡3卡4卡新区 | 亚洲色大情网站www| 亚洲AV无码国产丝袜在线观看| 日本免费一区二区三区最新| 美女内射无套日韩免费播放| 一区二区视频免费观看| 亚洲欧洲日韩极速播放| 亚洲色图在线播放| 亚洲伊人成无码综合网| 免费看AV毛片一区二区三区| 在线观看免费中文视频| 光棍天堂免费手机观看在线观看| 免费人成在线观看播放a|