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>

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值