Struts2攔截器學(xué)習(xí)

          Posted on 2008-02-17 17:14 flustar 閱讀(3860) 評(píng)論(3)  編輯  收藏 所屬分類: Struts2
            一、什么是攔截器?

          提到攔截器,使我不得不想起武俠劇中劫匪們常說的一句話:“此山是我開,此樹是我栽,要打此路過,留下買路財(cái)!”。難不成程序中也有“打劫”的,說的沒錯(cuò),攔截器就是個(gè)打劫的。在現(xiàn)實(shí)生活中,劫匪劫的大都是錢財(cái),當(dāng)然也有別的什么,那么程序中的“劫匪”劫的又是什么呢?或者說程序中為什么需要它?在我們的日常編程中少不了寫一些重復(fù)的代碼,例如在一個(gè)地方中寫了一段代碼,后來發(fā)現(xiàn)這段代碼在其它地方中同樣需要,在傳統(tǒng)的編程中我們一定會(huì)采取復(fù)制、粘貼的辦法。如果這段代碼只在這一兩個(gè)處需要,我們采取這種辦法,還說的過去,但是如果系統(tǒng)對(duì)這段代碼過于依賴,也就是這段代碼在系統(tǒng)中出現(xiàn)的過多,如果那一天我們發(fā)現(xiàn)這段代碼中在某些地方還需要完善,我們是不是要著個(gè)修改它們呢?我估計(jì)沒有人會(huì)這么做,它嚴(yán)重違反了軟件開發(fā)中一條非常重要的DRY規(guī)則,不寫重復(fù)代碼。說了這么多你一定知道我們?yōu)槭裁葱枰诔绦蛑信粋€(gè)“劫匪”了吧。這個(gè)“劫匪”就是并不是劫取什么東西,只是為了在某個(gè)程序執(zhí)行前后,動(dòng)態(tài)的增加一些功能(以前所寫通用代碼塊)或進(jìn)行一些檢查工作。那么這個(gè)攔截器到底是怎么實(shí)現(xiàn)的呢?實(shí)際上它是用Java中的動(dòng)態(tài)代理來實(shí)現(xiàn)的,具體可以參考設(shè)計(jì)模式學(xué)習(xí)筆記(十六)—Proxy模式》。

          二、攔截器在Struts2中的應(yīng)用

          對(duì)于Struts2框架而言,正是大量的內(nèi)置攔截器完成了大部分操作。像params攔截器將http請(qǐng)求中參數(shù)解析出來賦值給Action中對(duì)應(yīng)的屬性。Servlet-config攔截器負(fù)責(zé)把請(qǐng)求中HttpServletRequest實(shí)例和HttpServletResponse實(shí)例傳遞給Action……struts2內(nèi)置的攔截器有很多,在此我就不一一列舉了,具體可以參考《Struts2中有關(guān)struts-default.xml,struts.xml,struts.properties文件詳解》。

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

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

          publicinterface Interceptor extends Serializable {

              void destroy();

              void init();

              String intercept(ActionInvocation invocation) throws Exception;

          }

          1)    init():在攔截器執(zhí)行之前調(diào)用,主要用于初始化系統(tǒng)資源。

          2)    destroty():init()對(duì)應(yīng),用于攔截器執(zhí)行之后銷毀資源。

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

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

          下面創(chuàng)建一個(gè)判斷用戶是否登錄的攔截器。代碼如下:

          /** 
           *
           * 
          @author <a href="mailto:flustar2008@163.com">flustar</a>
           * 
          @version 1.0 
           * Creation date: Feb 12, 2008 5:05:28 PM
           
          */


          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{

                          
          // 存在的情況下進(jìn)行后續(xù)操作。

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

                          
          return actionInvocation.invoke();

                      }
           else {

                          
          // 否則終止后續(xù)操作,返回LOGIN

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

                          
          return Action.LOGIN;

                      }


                  }



              }



          創(chuàng)建好攔截器后,還不能使用,還需要我們?cè)?/span>struts.xml中配置一下。

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

          <interceptors>

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

          </interceptors>

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

          <action name=" " class=" " >

                     <result> </result>

                     <interceptor-ref name="checkLogin" />

          </action>

          一旦我們?yōu)槟硞€(gè)action引用了自定義的攔截器,struts2默認(rèn)的攔截器就不會(huì)再起作用,因此還需要引用默認(rèn)攔截器。

          <action name=" " class=" " >

                     <result> </result>

                     <interceptor-ref name="checkLogin" />

                               <interceptor-ref name="defaultStack" />

          </action>

          但是我們這么做似乎也不太方便,因?yàn)槿绻麛r截器checkLogin需要被多個(gè)action引用的話,每一個(gè)都要配置一遍太麻煩了。我們可以把它定義成默認(rèn)的攔截器。

          <interceptors>

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

                     <!—-定義一個(gè)攔截器棧-->

                     <interceptor-stack name="mydefault">

                        <interceptor-ref name="defaultStack" />

                        <interceptor-ref name="checkLogin" />

                     </interceptor-stack>

          </interceptors>

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

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

          <interceptor-ref name="  ">

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

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

          </interceptor-ref>

          exculdeMethods:是不被攔截的方法,如果有多個(gè)以逗號(hào)分隔。

          includeMethods:需要被攔截的方法,如果有多個(gè)以逗號(hào)分隔。

          Feedback

          # re: Struts2攔截器學(xué)習(xí)[未登錄]  回復(fù)  更多評(píng)論   

          2008-02-18 10:13 by apple0668
          攔截器確實(shí)很強(qiáng)大,學(xué)習(xí)了。

          # re: Struts2攔截器學(xué)習(xí)  回復(fù)  更多評(píng)論   

          2008-07-28 14:08 by 葉依萱
          很不錯(cuò)試試去~~~~~

          # re: Struts2攔截器學(xué)習(xí)  回復(fù)  更多評(píng)論   

          2008-08-23 15:01 by 李冬美
          不錯(cuò),很詳細(xì),我也要去學(xué)習(xí)學(xué)習(xí)!

          posts - 146, comments - 143, trackbacks - 0, articles - 0

          Copyright © flustar

          主站蜘蛛池模板: 临江市| 海门市| 金平| 望都县| 正定县| 当雄县| 巴东县| 卢龙县| 临湘市| 新田县| 柞水县| 淳化县| 阿荣旗| 介休市| 化德县| 玉田县| 正定县| 山丹县| 白银市| 工布江达县| 汽车| 灵台县| 八宿县| 周口市| 平顶山市| 根河市| 昌黎县| 麻栗坡县| 上栗县| 河西区| 东明县| 彰武县| 三穗县| 内乡县| 泌阳县| 双桥区| 勐海县| 紫阳县| 金昌市| 宜昌市| 柘城县|