struts2自定義攔截器實現的分析說明附帶代碼

Struts2內建攔截器

     Strus2框架內建了大量的攔截器完成了框架幾乎70%的工作,比如,params攔截器將HTTP請求中的參數解析出來,設置成Action的屬性;servlet-config攔截器直接將HTTP請求中的HttpServletRequest實例和HttpServletResponse實例傳給Action;fileUpload攔截器負責解析請求參數中的文件域,並將一個文件域設置成Action的3個屬性...

由於默認的struts攔截器棧中定義了許多框架的常用操作,且若Action中使用了自定義攔截器,struts-default包中定義的defaultStack將不起作用,從而無法完成HTTP參數映射到Action各屬性的過程,因此大部分情況下,爲某個Action指定了相應的攔截器後,組合使用多個攔截器/攔截器棧,或者自定義一個攔截器棧,其中包含對defaultStack的引用。

3.攔截器的實現原理

 定義接口

public interface Dog {     public void info();     public void run(); 

定義接口實現類

 

public class DogImpl implements Dog{       public void info() {         ...    }            public void run(){         ...     }  }

系統攔截器類

 

public class DogIntercepter {      public void method1(){}      public void method2(){} }

上面只是些普通的JAVA類,實現攔截器功能關鍵是下面的代理類

 

 public class ProxyHandler implemtsInvocationHandler {     private Objecttarget;//需被代理的目標對象           //創建攔截器實例     DogIntercepter di = newDogIntercepter();     //執行代理的目標方法時,該Invoke方法會被自動調用     public Object invoke(Object proxy, Methodmethod, Object[] args) {         Objectresult = null;        if(method.getName().equals("info"){             di.methord1();             result =method.invoke(tart,args);            di.method2();         }         else {             result =methos.invoke(target,args);        }         return result;     }               public void setTarget(Objecto){         this.target=o;     } }

代理工廠類

 

public class MYProxyFactory{     public static Object getProxy(Objectobject){         ProxyHandler handler = newProxyHandler();        handler.setTarget(object);        return Proxy.newProxyInstance(Dogimpl.class.getClassLoader(),object.getClass().getInterfaces(),handler);    } }

主程序

 

public class Test{     public static void main(String[]args){         Dog targetObject = newDogImpl();         Dog dog = null;           //以目標對象創建代理         Object proxy =MyProxyFactory.getProxy(targetObject);        if(proxy instance of Dog) {            dog=(Dog)proxy;         }                   dog.info();         dog.run();     } }

上例通過JDK動態代理,在執行目標方法之前調用攔截器方法一,在執行目標方法之後調用攔截器方法二。

 

4. 攔截器及攔截器棧的配置

在Struts.xml中配置攔截器

<interceptor name="name"class="class"/>

還可以指定攔截器參數

 

<interceptor name="name"class="class">

 

     <param name="param name">…</param>

 

</interceptor>

在Struts.xml中配置攔截器棧

攔截器棧是由多個攔截器組成的,即一個攔截器棧包含了多個攔截器。

 

<interceptor-stack name="stackname">

 

     <interceptor-ref name="interceptor 1"/>

 

     <interceptor-ref name="interceptor 2"/>

 

     <interceptor-ref name="interceptor stack 1"/>

 

</interceptor>

提示:一個包中所有的攔截器都應定義在<interceptors…/>元素中

 

5. 攔截器及攔截器棧的使用

通過<interceptor-ref…/>元素來使用攔截器和攔截器棧。下面是在Action中定義攔截器的配置示例:

 

<action name="..."   ...>    ......     <!-- interceptor 1-->    <interceptor-refname="int1"/>     <!--interceptor 2 -->    <interceptor-refname="int2">        <param name="...">...</param>     </nterceptor-ref> </action>

7.使用自定義攔截器

實現攔截器類

 

如果用戶要開發自己的攔截器類,有如下兩種方式:

 

實現com.opensymphony.xwork2.interceptor.Interceptor接口

繼承AbstractInterceptor類

Interceptor定義如下:

 

public interface Interceptor extendsSerializable {

 

   /**

    * Called to let an interceptor clean up any resources it has allocated.

    */

   void destroy();

 

   /**

    * Called after an interceptor is created, but before any requests areprocessed using

    * {@link #intercept(com.opensymphony.xwork2.ActionInvocation) intercept}, giving

    * the Interceptor a chance to initialize any needed resources.

    */

   void init();

 

   /**

    * Allows the Interceptor to do some processing on the request beforeand/or after the rest of the processing of the

    * request by the {@link ActionInvocation} or to short-circuit theprocessing and just return a String return code.

    *

    * @param invocation the action invocation

    * @return the return code, either returned from {@linkActionInvocation#invoke()}, or from the interceptor itself.

    * @throws Exception any system-level error, as defined in {@linkcom.opensymphony.xwork2.Action#execute()}.

    */

   String intercept(ActionInvocation invocation) throws Exception;

 

}

我們的攔截器必須重寫Interceptor接口中的intercept方法,該方法有一個ActionInvocation的參數,該參數實例可以用於獲得被攔截的Action實例。

 

MyAction action =(MyAction)invocation.getAction();

一旦獲得了Action實例,幾乎獲得了Action的全部控制權:

 

可以實現將HTTP請求參數解析出來,設置成Action的屬性(這是系統攔截器乾的事情)

可以直接將HTTP請求中的HttpServletRequest實例和HttpServletResponse實例傳給Action(這是servlet-config攔截器乾的事情)

…..

下面是個自定義攔截器類的例子

 

攔截器類

 

importcom.jj.test.redirect.RedirectTest;

importcom.opensymphony.xwork2.ActionInvocation;

import com.opensymphony.xwork2.interceptor.AbstractInterceptor;

 

public class MyInterceptor extendsAbstractInterceptor{   

   @Override

   public String intercept(ActionInvocation invocation) throws Exception {

       RedirectTest action = (RedirectTest)invocation.getAction();

       System.out.println(action.getTarget());

       System.out.println("Start------");

       long start = System.currentTimeMillis();

       

       //執行Action的exceute方法

       String result = invocation.invoke();

       

       long end = System.currentTimeMillis();

       System.out.println("End------"+(end-start));

       return result;

   }

 

}

ActionInvocation 類常用方法

 

getAction方法 -獲取Action實例

getInvocationContext方法 - 獲取ActionContext實例

invoke方法 - 執行該攔截器的後一個攔截器,或者直接執行Action的execute方法

在intercept方法中獲取Session

 

ActionContext ctx =invocation.getInvocationContext();

 

Map session = ctx.getSession();

struts.xml中的配置

 

<package name="redir"namespace="/redir" extends="struts-default">         <interceptors>             <interceptor name="MyInterceptor"class="com.jj.test.interceptor.MyInterceptor"></interceptor>         </interceptors>         <default-interceptor-refname="MyInterceptor"/>        <action name="RedirTest"class="com.jj.test.redirect.RedirectTest">                       <result name="SUCCESS"type="dispatcher">/${target}.jsp</result>         </action>  </package>

 

發佈了93 篇原創文章 · 獲贊 10 · 訪問量 21萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章