一.拦截器概念
Strrurs拦截器是可插拔式的拦截器:如果我们要使用某个拦截器,只需要在配置文件中应用该拦截器即可。
Struts拦截器由struts-default.xml,struts.xml等配置文件中进行管理。
Struts2中已经默认启动了大量通用功能的拦截器(这些拦截器以name-class对的形式配置在struts-default.xml文件中),只要我们配置Action的package继承了struts-default包,这些拦截器就会起作用。
拦截器几乎完成了Sturts2框架70%的工作。
Sturts2几个常用内建拦截器的介绍:
1)conversation:这是一个处理类型转换错误的拦截器,它负责将类型转换错误从ActionContext中取出,并转换成Action的FieldError错误。
2)Exception:这个拦截器负责处理异常,它将异常映射成结果。
3)fileUpload:这个拦截器主要用于文件上传,它负责解析表单中文件域的内容。
4)i18n:这是支持国际化的拦截器,它负责把所选的语言、区域放入用户Session中。
5)params:这是最基本的一个拦截器,它负责解析HTTP请求中的参数,并将参数值设置成Action对应的属性值。
6)scope:这是范围转换拦截器,它可以将Action状态信息保存到HttpSession范围,或者保存到ServletContext范围内。
7)token:这个拦截器主要用于阻止重复提交,它检查传到Action中的token,从而防止多次提交。
只要我们定义的包继承了struts-default包,就可以直接使用这些拦截器。
2.配置拦截器
1.定义一个拦截器
在strust.xml中定义:
<interceptor name="拦截器名" class="拦截器实现类"/>
2.定义拦截器的时候传入参数:
<interceptor name="拦截器名" class="拦截器实现类"> <!--可以加0个或N个参数--> <param name="参数名">参数值</param> </interceptor>
3.定义拦截器栈:
<interceptor-stack name="拦截器栈名"> <interceptor-ref name="拦截器一"/> <interceptor-ref name="拦截器二"/> ... </interceptor-stack>(拦截器栈中也可以包含拦截器栈)
4.通过为<interceptor-ref.../>元素增加<para.../>子元素,就可以在使用拦截器的时候为参数指定值:
<interceptor-stack name="拦截器栈名"> <interceptor-ref name="拦截器一"> <param name="参数名1">参数值1</param> <param name="参数名2">参数值2</param> <interceptor-ref/> <interceptor-ref name="拦截器二"/> ... </interceptor-stack>
5.定义所有的拦截器:
在struts.xml中,把所有拦截器定义在
<interceptors></interceptor>中
6.使用拦截器
在Action中配置拦截器的示例:
struts.xml:
<pre name="code" class="html"><interceptors> <!--定义第一个拦截器--> <interceptor name="mysimple" class="cn.edu.hpu.Int.SimpleInterceptor"/> <!--定义第二个拦截器--> <interceptor name="later" class="cn.edu.hpu.Int.LaterInterceptor"> <param name="name">第一个拦截器</param> </interceptor> </interceptors> <package name="test"> <action name="login" class="cn.edu.hpu.action.LoginAction"> <result name="error">/error.jsp</result> <result name="success">/success.jsp</result> <!--使用系统默认的拦截器栈--> <interceptor-ref name="defaultStack"/> <!--使用第一个拦截器--> <interceptor-ref name="mysimple"/> <!--使用第二个拦截器--> <interceptor-ref name="later"> <!--为action指定拦截器参数,覆盖name参数的默认值--> <param name="name">动态参数</param> </interceptor> </action> </package>
上面的配置文件的代码一共使用了三个拦截器(栈),其中default是系统默认的拦截器。而mysimple和later就是用户自定义的拦截器,因此在执行Login之前,这三个拦截器都会起作用。注意的是,Actionx显式应用了某个拦截器,则默认的拦截器不会起作用;如果该Action需要使用该默认拦截器,则必须手动配置拦截器的引用。所以这里为了应用系统默认的拦截器defaultStack拦截器栈,我们在配置文件中显式地应用了默认拦截器。
7.配置默认拦截器
配置默认拦截器使用<default-interceptor-ref.../>元素,该元素作为<package.../>元素的子元素使用,为该包下的所有Action配置默认的拦截器。要注意的是,只有当Action中没有显式应用拦截器时,该Action所在的包的默认拦截器才会生效。配置例子:
<package name="包名"> <interceptors> <interceptor.../> <interceptor-stack.../> </interceptors> <!--配置该包下的默认拦截器,既可以是拦截器,也可以是拦截器栈--> <default-interceptor-ref name="拦截器名或拦截器栈名"/> </package>
8.实现拦截器类
如果用户要开发拦截器类,应该实现com.opensymphony.xwork2.ActionInvocation接口,该接口的类定义代码如下:
public class MyInterceptor implements Interceptor{ public void destroy() { } public void init() { } //写好了一个拦截(计算了一个action运行的时间) public String intercept(ActionInvocation invocation) throws Exception { long start=System.currentTimeMillis(); String r=invocation.invoke(); long end=System.currentTimeMillis(); System.out.println("Action Time="+(end-start)); return r; } }其中init()方法,在拦截器执行拦截之前调用该方法。
destory方法,在拦截器实例被销毁之前。
intercept(ActionInvocation invocation)方法是用户要实现的拦截动作。
Stuts2还提供了一个AbstractInterceptor类,该类提供了一个init和destory方法的空实现,如果我们实现的拦截器不需要打开资源,则可以无需实现这连个方法。可见,继承AbstractInterceptor类来实现自定义拦截器会更加简单。
下面实现了一个简单的拦截器:
import cn.edu.hpu.action.LoginAction; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.AbstractInterceptor; public class SimpleInterceptor extends AbstractInterceptor { //简单拦截器的名字 private String name; public void setName(String name) { this.name = name; } @Override public String intercept(ActionInvocation invocation) throws Exception { //取得被拦截的Action实例的方法 LoginAction action=(LoginAction)invocation.getAction(); //执行该拦截器的后一个拦截器 //如果该拦截器后没有其他拦截器,则直接执行Action的execute方法 String result=invocation.invoke(); return result; } }
当我们执行intercept(ActionInvocation invocation)方法时,可以获得ActionInvocation参数,这个参数又可以获得被拦截的Action实例,一旦获得了Action实例,几乎获得了全部的控制权:可以实现将HTTP请求中的参数解析出来,设置成Action的属性(这是系统param拦截器完成的事情);也可以直接将HTTP请求中的HttpServletRequest实例和httpServletResponse实例传给Action(这是servlet-config拦截器完成的事情)......当然,也可以实现应用相关的逻辑。
转载请注明出处:http://blog.csdn.net/acmman/article/details/47086361