struts2拦截器详解

来源:互联网 发布:ubuntu ant 编辑:程序博客网 时间:2024/05/22 13:26

一、拦截器概念

    拦截器(Interceptor)是Struts2的一个重要特性,它可以在Action 执行前和执行后拦截调用。Struts2的拦截器和Servlet过滤器类似。在执行Action的execute方法之前,Struts2会首先执行在struts.xml中引用的拦截器,在执行完所有引用的拦截器的intercept方法后,会执行Action的execute方法。拦截器的核心就是面向接口的反射调用和代理模式。Struts2将核心功能放到拦截器中实现而不是分散到Action 中实现,有利于系统的解耦。

  在Struts2 中编写拦截器类,必须实现com.opensymphony.xwork2.interceptor.Interceptor 接口,该类定义了三个方法:



       其中intercept方法是拦截器的核心方法,所有安装的拦截器都会调用这个方法。在Struts2中已经在struts-default.xml中预定义了一些自带的拦截器,如timer、params等。如果在<package>标签中继承struts-default,则当前package就会自动拥有struts-default.xml中的所有配置。在struts-default.xml中有一个默认的引用,在默认情况下(也就是<action>中未引用拦截器时)会自动引用一些拦截器。这个默认的拦截器引用见struts-default.xml文件

几个简单的拦截器的使用方法 
一、记录拦截器和execute方法的执行时间(timer) 
timer是Struts2中最简单的拦截器,这个拦截器对应的类com.opensymphony.xwork2.interceptor.TimerInterceptor。它的功能是记录execute方法和其他拦截器(在timer后面定义的拦截器)的intercept方法执行的时间总和。如下面的配置代码所示:


<action name="first" class="action.FirstAction">
    <interceptor-ref name="logger"/>
    <interceptor-ref name="timer" />
</action>

由于在timer后面没有其他的拦截器定义,因此,timer只能记录execute方法的执行时间

在使用timer拦截器时,需要commons-logging.jar的支持。将logger引用放到timer的后面,就可以记录logger拦截器的intercept方法和Action的execute方法的执行时间总和,代码如下:
<action name="first" class="action.FirstAction">
    <interceptor-ref name="timer" />
    <interceptor-ref name="logger"/>
</action>
大家可以使用如下的Action类来测试一下timer拦截器:
import com.opensymphony.xwork2.ActionSupport;
public class FirstAction extends ActionSupport          


{
       public String execute() throws Exception
       {
           Thread.sleep(1000); // 延迟1秒
           return null;
       }
}

token拦截器是用于防止form重复提交的,使用时需要配置目标action被该拦截器拦截
<action….>
<interceptor-ref name=“defaultStack”/>
<interceptor-ref name=“token”/>

</action
在view层面的form中要使用如下标签
<s:token/>

使用拦截器栈 
为了能在多个动作中方便地引用同一个或几个拦截器,可以使用拦截器栈将这些拦截器作为一个整体来引用。拦截器栈要在<package>标签中使用<interceptors>和子标签<interceptor-stack>来定义。代码如下:
<package name="demo" extends="struts-default" >
    <interceptors>
        <interceptor-stack name="mystack">
            <interceptor-ref name="timer" />
            <interceptor-ref name="logger" />
            <interceptor-ref name="params" />
            <interceptor-ref name="static-params" />
        </interceptor-stack>
    </interceptors>


    <action name="first" class="action.FirstAction">
        <param name="who">比尔</param>
        <interceptor-ref name="mystack"/>            
    </action>
</package>


二、实现自已的拦截器 

实现一个拦截器非常简单。实际上,一个拦截器就是一个普通的类,只是这个类必须实现com.opensymphony.xwork2.interceptor.Interceptor接口。

示例:

package com.itjob.wujin.interceptor;


import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.Interceptor;
public class MyInterceptor implements Interceptor {
public void init() {
System.out.println("拦截器init()");
}
public String intercept(ActionInvocation arg0) throws Exception {
System.out.println("before");
String result = arg0.invoke();//与Servlet过滤器中调用FilterChain.doFilter方法类似如果在当前拦截器后面还有其他的拦截器,则invoke方法就是调用后面拦截器的intercept方法,否则,invoke会调用Action类的execute方法(或其他的执行方法)。 
System.out.println("after()");
return result;
}
public void destroy() {
System.out.println("拦截器destroy()");
}
}

配置:

<package name="struts2" extends="struts-default">
<interceptors>
<interceptor name="myInterceptor“class="com.itjob.wujin.interceptor.MyInterceptor">
</interceptor>
</interceptors>

<action name="login" class="com.itjob.wujin.action.LoginAction">
<result>/success.jsp</result>
<result name="input">/login.jsp</result>
</action>

<action name="reg" class="com.itjob.wujin.action.RegAction">
<result>/success.jsp</result>
<result name="input">/reg1.jsp</result>
<interceptor-ref name="myInterceptor"></interceptor-ref>
</action>
</package>
interceptor 里带参数 param
<interceptors>
<interceptor name="myInterceptor“class="com.itjob.wujin.interceptor.MyInterceptor">
<param name=“hello">world</param>
</interceptor>
</interceptors>
声明了元素param,使用则在拦截器中需对应定义属性 private String hello;,声明其setter 和getter 函数,则参数值会自动赋值。


三、拦截器工作方式

拦截器围绕着Action 和Result 的执行而执行。


四、抽象类简化拦截器

       为了简化拦截器的开发,Struts2 还提供了一个抽象类:com.opensymphony.xwork2.interceptor.AbstractInterceptor,它实现了Interceptor接口,并给出了init()和destroy() 方法的空实现,  这是一种Adapter设计模式。


五、方法拦截器

Action 中有多个方法,Struts2 还提供了粒度更小的方法拦截器抽象基类:com.opensymphony.xwork2.interceptor.MethodFilterInterceptor


package com.itjob.wujin.interceptor;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor;

public class MyInterceptor extends MethodFilterInterceptor {
@Override
protected String doIntercept(ActionInvocation arg0) throws Exception {
System.out.println("before");
String result = arg0.invoke();
System.out.println("after()");
return result;
}
}

MethodFilterInterceptor通过指定included / excluded 方法列表来选择拦截或排除的方法,可以设置参数如下:
excludeMethods – 要排除的方法
includeMethods – 要拦截的方法
includeMethods 优先级要高于excludeMethods,一定会被拦截,不管是否排除在外。


<action name="reg" class="com.itjob.wujin.action.RegAction">
<result>/success.jsp</result>
<result name="input">/reg1.jsp</result>
<interceptor-ref name="defaultStack"></interceptor-ref>
<interceptor-ref name="myInterceptor">
<param name="includeMethods">add</param>
<param name="excludeMethods">add,execute</param>
</interceptor-ref>
</action>



0 0
原创粉丝点击