隨筆 - 312, 文章 - 14, 評論 - 1393, 引用 - 0

          導航

          <2008年5月>
          27282930123
          45678910
          11121314151617
          18192021222324
          25262728293031
          1234567

          公告

          關注我的新浪微博

          我的著作









          常用鏈接

          留言簿(126)

          我參與的團隊

          隨筆分類(818)

          隨筆檔案(310)

          文章分類(1)

          文章檔案(8)

          相冊

          ADSL、3G查詢

          CSDN

          eclipse

          ibm

          Java EE

          Linux

          Web

          云服務

          代理網站

          關注的網站

          協議

          喜歡的Blog

          國內廣告平臺

          圖書出版

          在線培訓

          開發工具

          微博客戶端

          手機鈴聲

          操作系統

          • ReactOS
          • 一個與windowXP/2003兼容的操作系統

          數學

          文件格式

          源碼資源

          移動(Mobile)

          編程語言

          英語學習

          最新隨筆

          搜索

          •  

          積分與排名

          • 積分 - 1973561
          • 排名 - 6

          最新評論

          閱讀排行榜

          評論排行榜

          Struts2教程9:實現自已的攔截器

          本文為原創,如需轉載,請注明作者和出處,謝謝!

          上一篇:Struts2教程8:攔截器概述

              在上一篇中介紹了Struts2攔截器的原理,在這一篇中我們將學習一下如何編寫自己的攔截器。

          一、攔截器的實現

               實現一個攔截器非常簡單。實際上,一個攔截器就是一個普通的類,只是這個類必須實現com.opensymphony.xwork2.interceptor.Interceptor接口。Interceptor接口有如下三個方法:


          public interface Interceptor extends Serializable 
          {
              
          void destroy();
              
          void init();
              String intercept(ActionInvocation invocation) 
          throws Exception;
          }

          其中initdestroy方法只在攔截器加載和釋放(都由Struts2自身處理)時執行一次。而intercept方法在每次訪問動作時都會被調用。Struts2在調用攔截器時,每個攔截器類只有一個對象實例,而所有引用這個攔截器的動作都共享這一個攔截器類的對象實例,因此,在實現Interceptor接口的類中如果使用類變量,要注意同步問題。

          下面我們來實現一個簡單的攔截器,這個攔截器通過請求參數action指定一個攔截器類中的方法,并調用這個方法(我們可以使用這個攔截器對某一特定的動作進行預處理)。如果方法不存在,或是action參數不存在,則繼續執行下面的代碼。如下面的URL

          http://localhost:8080/struts2/test/interceptor.action?action=test

          訪問上面的url后,攔截器會就會調用攔截器中的test方法,如果這個方法不存在,則調用invocation.invoke方法,invoke方法和Servlet過濾器中調用FilterChain.doFilter方法類似,如果在當前攔截器后面還有其他的攔截器,則invoke方法就是調用后面攔截器的intercept方法,否則,invoke會調用Action類的execute方法(或其他的執行方法)。

          下面我們先來實現一個攔截器的父類ActionInterceptor。這個類主要實現了根據action參數值來調用方法的功能,代碼如下:


          package interceptor;

          import com.opensymphony.xwork2.ActionInvocation;
          import com.opensymphony.xwork2.interceptor.Interceptor;
          import javax.servlet.http.*;
          import org.apache.struts2.*;

          public class ActionInterceptor implements Interceptor
          {
              
          protected final String INVOKE = "##invoke";
             
              
          public void destroy()
              {
                  System.out.println(
          "destroy");
              }

              
          public void init()
              {
                  System.out.println(
          "init");
              }

              
          public String intercept(ActionInvocation invocation) throws Exception
              {    
                  HttpServletRequest request 
          = ServletActionContext.getRequest();
                  String action 
          = request.getParameter("action");
                  System.out.println(
          this.hashCode());
                  
          if (action != null)
                  {
                      
          try
                      {
                          java.lang.reflect.Method method 
          = this.getClass().getMethod(action);
                          String result 
          = (String)method.invoke(this);
                          
          if(result != null)
                          {
                              
          if(!result.equals(INVOKE))
                                  
          return result;
                          }
                          
          else
                              
          return null;
                      }
                      
          catch (Exception e)
                      {
                      }
                  }
                  
          return invocation.invoke();
              }
          }

          從上面代碼中的intercept方法可以看出,在調用action所指定的方法后,來判斷返回值。可能發生的情況有三種:

          1.        返回值為null,執行return null

          2.        返回值為INVOKE,執行return invockation.invoke()

          3.        其他情況,執行return result result表示指定方法的返回值,如上面代碼所示。

              在實現完上面的攔截器父類后,任何繼承于ActionInterceptor類的攔截器都可以自動根據action的參數值調用自身的相應方法。下面我們來實現一個擁有兩個動作方法testprint的攔截器類。代碼如下:


          package interceptor;

          import javax.servlet.http.HttpServletResponse;
          import org.apache.struts2.ServletActionContext;

          public class MultiMethodInterceptor extends ActionInterceptor
          {
              
          public String test() throws Exception
              {
                  HttpServletResponse response 
          = ServletActionContext.getResponse();
                  response.getWriter().println(
          "invoke test");
                  
          return this.INVOKE;
              }

              
          public String print() throws Exception
              {
                  HttpServletResponse response 
          = ServletActionContext.getResponse();
                  response.getWriter().println(
          "invoke print");

                  
          return null;
              }
          }

          test方法返回了INVOKE,因此,在執行完這個方法后,Struts2會接著調用其他攔截器的intercept方法或Action類的execute方法。而print方法在執行完后,只是返回了null,而不再調用其他的方法了,也就是訪問如下的url時,動作的execute方法將不會執行:

              http://localhost:8080/struts2/test/ddd.action?action=print

              下面我們來實現一個Action類,代碼如下:

          package action;

          import org.apache.struts2.*;
          import com.opensymphony.xwork2.ActionSupport;

          public class InterceptorAction extends ActionSupport
          {
              
          public String abcd() throws Exception
              {
                  ServletActionContext.getResponse().getWriter()
                          .println(
          "invoke abcd");
                  
          return null;
              }
          }

          在這個Action類中,只有一個abcd方法,實際上,這個方法相當于execute方法,在下面會設置動作的method屬性為abcd。下面我們來在struts.xml中定義攔截器類和動作,代碼如下:


          <?xml version="1.0" encoding="UTF-8" ?>
          <!DOCTYPE struts PUBLIC
              "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
              "http://struts.apache.org/dtds/struts-2.0.dtd"
          >
          <struts>
              
          <package name="demo" extends="struts-default" namespace="/test">
                  
          <interceptors>
                      
          <interceptor name="method" class="interceptor.MultiMethodInterceptor" />
                          
          <interceptor-stack name="methodStack">
                              
          <interceptor-ref name="method" />
                              
          <interceptor-ref name="defaultStack" />
                          
          </interceptor-stack>
                  
          </interceptors>

                  
          <action name="interceptor" class="action.InterceptorAction" method="abcd">
                      
          <interceptor-ref name="methodStack" />
                  
          </action>
              
          </package>
          </struts>

          在配置上面的methodStack攔截器時要注意,最好在后面引用defaultStack,否則很多通過攔截器提供的功能將失去。

          OK,現在訪問如下的URL

              http://localhost:8080/struts2/test/ddd.action?action=test

          在瀏覽器中將會出現如下的字符串:

              invoke test

          invoke abcd

          而如果訪問http://localhost:8080/struts2/test/ddd.action?action=print,將會只出現如下的字符串:

              invoke print

          大家可以看出,訪問這個url時并沒有調用abcd方法。如果隨便指定的action值的話,則只調用abcd方法,如訪問http://localhost:8080/struts2/test/ddd.action?action=aaa,就只會輸出invoke abcd


          二、攔截器的參數

             
          我們在使用很多Struts2內置的攔截器時會發現有很多攔截器都帶參數,當然。我們自己做的攔截器也可以加上同樣的參數。有兩個參數比較常用,這兩個參數是includeMethodsexcludeMethods,其中includeMethods指定了攔截器要調用的Action類的執行方法(默認是execute),也就是說,只有在includeMethods中指定的方法才會被Struts2調用,而excludeMethods恰恰相反,在這個參數中指定的執行方法不會被Struts2調用。如果有多個方法,中間用逗號(,)分隔。在Struts2中提供了一個抽象類來處理這兩個參數。這個類如下:

          com.opensymphony.xwork2.interceptor.MethodFilterInterceptor

             
          如有繼承于這個類的攔截器類都會自動處理includeMethodsexcludeMethods參數,如下面的攔截器類所示:

          package interceptor;

          import com.opensymphony.xwork2.ActionInvocation;
          import com.opensymphony.xwork2.interceptor.*;

          public class MyFilterInterceptor extends MethodFilterInterceptor
          {
              
          private String name;
              
          public String getName()
              {
                  
          return name;
              }
              
          public void setName(String name)
              {
                  
          this.name = name;
              }
              @Override
              
          protected String doIntercept(ActionInvocation invocation) throws Exception
              {
                  System.out.println(
          "doIntercept");
                  System.out.println(name);
                  
          return invocation.invoke();
              }
          }

              MethodFilterInterceptor的子類需要實現doIntercept方法(相當于Interceptorintercept方法),如上面代碼所示。在上面的代碼中還有一個name屬性,是為了讀取攔截器的name屬性而設置的,如下面的配置代碼所示:


          <?xml version="1.0" encoding="UTF-8" ?>
          <!DOCTYPE struts PUBLIC
              "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
              "http://struts.apache.org/dtds/struts-2.0.dtd"
          >
          <struts>
              
          <package name="demo" extends="struts-default" namespace="/test">
                  
          <interceptors>
                      
          <interceptor name="method" class="interceptor.MultiMethodInterceptor" />
                          
          <interceptor name="filter"
                              class
          ="interceptor.MyFilterInterceptor">
                              
          <param name="includeMethods">abcd</param>
                              
          <param name="name">中國</param>
                          
          </interceptor>
                          
          <interceptor-stack name="methodStack">
                              
          <interceptor-ref name="method" />
                              
          <interceptor-ref name="filter" />
                              
          <interceptor-ref name="defaultStack" />
                          
          </interceptor-stack>
                  
          </interceptors>

                  
          <action name="interceptor" class="action.InterceptorAction" method="abcd">
                      
          <interceptor-ref name="methodStack" />
                  
          </action>
              
          </package>
          </struts>

              再次訪問http://localhost:8080/struts2/test/ddd.action?action=test, Struts2就會調用MyFilterInterceptordoIntercept方法來輸出name屬性值。如果將上面的includeMethods參數值中的abcd去掉,則Action類的abcd方法不會被執行。

          下一篇:Struts2教程10:國際化







          Android開發完全講義(第2版)(本書版權已輸出到臺灣)

          http://product.dangdang.com/product.aspx?product_id=22741502



          Android高薪之路:Android程序員面試寶典 http://book.360buy.com/10970314.html


          新浪微博:http://t.sina.com.cn/androidguy   昵稱:李寧_Lining

          posted on 2008-05-09 20:14 銀河使者 閱讀(18665) 評論(10)  編輯  收藏 所屬分類: Struts2 原創

          評論

          # re: Struts2教程9:實現自已的攔截器  回復  更多評論   

          博主介紹的很詳細.學習了.
          2008-05-16 01:46 | star

          # re: Struts2教程9:實現自已的攔截器  回復  更多評論   

          再次訪問http://localhost:8080/struts2/test/ddd.action?action=test, Struts2就會調用MyFilterInterceptor的doIntercept方法來輸出name屬性值。如果將上面的includeMethods參數值中的abcd去掉,則Action類的abcd方法不會被執行。

          這句話我還是不能理解
          加上includeMethods參數值abcd是會被執行;可你說去掉abcd就不會被執行我測試不對哦,去掉includeMethods參數值就等于沒有用這個特性,那樣的話test方法有INVOKE返回值還是會繼續執行下去。
          2008-05-20 13:34 | 小哥

          # re: Struts2教程9:實現自已的攔截器  回復  更多評論   

          是這樣的,struts2在調用所定義的攔截器的doIntercept方法后,最后會調用相應的動作類的執行方法,默認是execute。abcd只是修改了默認值,將執行方法由execute變成了abcd。如果在includeMethods參數中包含了abcd,那么Struts2在調用完所有的doIntercept方法后,就不會再調用abcd方法了。
          2008-05-20 15:25 | 銀河使者

          # re: Struts2教程9:實現自已的攔截器[未登錄]  回復  更多評論   

          @銀河使者

          樓主整理的文章和例子很不錯,贊一個。

          不過文章中最后一句話是有些歧義的,如樓上@小哥的問題。文中

          “如果將上面的includeMethods參數值中的abcd去掉,則Action類的abcd方法不會被執行。 ”

          這句話應該理解為這樣:

          “如果將上面的includeMethods參數值中的abcd去掉,則該過濾器對方法為‘abcd’請求將不做限制(也就是不執行過濾器MyFilterInterceptor的doIntercept方法),直接執行Action類的abcd的方法。 ”
          2009-02-03 17:32 | Sam

          # re: Struts2教程9:實現自已的攔截器  回復  更多評論   

          @Sam
          先謝謝你咯,如果不是看你在下面的解釋,可能我就卡在這里過不去了!
          2009-12-11 13:25 | 請求權

          # re: Struts2教程9:實現自已的攔截器  回復  更多評論   

          博主,在你的文章里我學到很多東西,非常感謝,但是對這點我不是很理解。上面this.getClass().getMethod(action);,好像this.getClass()得到的是ActionInterceptor 的Class對象,而不是對應action的Class對象啊,那么也不可能調用到aciton的方法啊?如果我說錯了請博主指點一下。
          2010-07-19 11:22 | liuyake

          # re: Struts2教程9:實現自已的攔截器  回復  更多評論   

          可以,很有收獲
          2012-03-26 09:28 |

          # re: Struts2教程9:實現自已的攔截器[未登錄]  回復  更多評論   

          11
          2012-03-27 17:59 | 222

          # re: Struts2教程9:實現自已的攔截器  回復  更多評論   

          ssssssssssssssssss
          2014-04-22 15:28 | ddddddddd

          # re: Struts2教程9:實現自已的攔截器  回復  更多評論   

          為什么我直接復制都跑不出來啊
          2014-07-28 16:18 | 側田
          主站蜘蛛池模板: 桐城市| 桂平市| 时尚| 宝丰县| 安化县| 定西市| 金沙县| 江华| 忻城县| 海口市| 武鸣县| 名山县| 工布江达县| 兰西县| 泰宁县| 全椒县| 扎赉特旗| 永春县| 吉木乃县| 乐都县| 施甸县| 鹤山市| 满洲里市| 鹤岗市| 印江| 雷州市| 内乡县| 湟源县| 宜兴市| 鄢陵县| 布尔津县| 梧州市| 剑河县| 天台县| 古蔺县| 玛多县| 阿图什市| 吉木萨尔县| 盖州市| 淮安市| 牙克石市|