拦截器是Struts2的核心所在。当需要扩展Struts2的功能时,只需要提供相应的拦截器,并将它配置在Struts容器中即可。反之,如果不需要某个功能,也只需要取消该拦截器即可。
定义拦截器使用<interceptor…/>元素。其格式为:
<interceptor name="拦截器名" class="拦截器实现类"></interceptor>
只要在<interceptor..>与</interceptor>之间配置<param…/>子元素即可传入相应的参数。其格式如下:
<interceptor name="myInterceptor" class="org.tool.MyInterceptor"> <param name="参数名">参数值</param> ... </interceptor>
通常情况下,一个Action要配置不仅一个拦截器,往往多个拦截器一起使用来进行过滤。这时就会把需要配置的几个拦截器组成一个拦截器栈。定义拦截器栈用<interceptor-stack name="拦截器栈名"/>元素,由于拦截器栈是由各拦截器组合而成的,所以需要在该元素下面配置<interceptor-ref …/>子元素来对拦截器进行引用。其格式如下:
<interceptor-stack name="拦截器栈名"> <interceptor-ref name="拦截器一"></interceptor-ref> <interceptor-ref name="拦截器二"></interceptor-ref> <interceptor-ref name="拦截器三"></interceptor-ref> </interceptor-stack>
注意:在配置拦截器栈时用到的拦截器必须是已经配置好的拦截器。拦截器栈也可以引用拦截器栈。
如果为包指定了某个拦截器,则该拦截器会对每个Action起作用,但是如果显式地为某个Action配置了拦截器,则默认的拦截器将不会起作用。默认拦截器用<default-interceptor-ref name=""/>元素来定义。每个包只能指定一个默认的拦截器,如果需要指定多个拦截器共同作为默认拦截器,则应该将这些拦截器定义成拦截器栈,然后把这个拦截器栈配置为默认的拦截器即可。
下面是默认拦截器的配置方法:
<package name="包名"> <interceptors> <interceptor name="拦截器一" class="拦截器实现类"></interceptor> <interceptor name="拦截器二" class="拦截器实现类"></interceptor> <interceptor-stack name="拦截器栈名"> <interceptor-ref name="拦截器一"></interceptor-ref> <interceptor-ref name="拦截器二"></interceptor-ref> </interceptor-stack> </interceptors> <default-interceptor-ref name="拦截器名或拦截器栈名"></default-interceptor-ref> </package>
Struts 2提供了一些接口或类供程序员自定义拦截器。如Struts 2提供了com.opensymphony.xwork2.interceptor.Interceptor接口,程序员只要实现该接口就可完成拦截器实现类。该接口的代码如下:
import java.io.Serializable; import com.opensymphony.xwork2.ActionInvocation; public interface Interceptor extends Serializable{ void init(); String intercept(ActionInvocation invocation) throws Exception; void destroy(); }
该接口中有三个方法:
init():该方法在拦截器被实例化之后、拦截器执行之前调用。
intercept(ActionInvocation invocation):该方法用于实现拦截的动作。该参数调用其invoke方法,将控制权交给下一个拦截器,或者交给Action类的方法。
destroy():该方法与init()方法对应,拦截器实例被销毁之前调用,用于销毁在init()方法中打开的资源。
Struts 2提供了AbstractInterceptor类,该类提供了init()方法和destory()方法的空实现。在一般的拦截器实现中,都会继承该类,因为一般实现的拦截器是不需要打开资源的,故无需实现这两个方法,继承该类会更简洁。
下面来配置拦截器,如果输入框中输入的内容是“hello”,返回当前页面。实现该功能只需要在原项目的基础上配置拦截器即可。首先编写拦截器实现类,代码如下:
package org.tool; import org.action.StrutsAction; import com.opensymphony.xwork2.Action; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.AbstractInterceptor; public class MyInterceptor extends AbstractInterceptor{ public String intercept(ActionInvocation arg0) throws Exception { // 得到StrutsAction类对象 StrutsAction action=(StrutsAction)arg0.getAction(); // 如果Action类中的name属性的值为"hello",返回错误页面 if(action.getName().equals("hello")){ return Action.ERROR; } // 继续执行其他拦截器或Action类中的方法 return arg0.invoke(); } }
在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="default" extends="struts-default"> <interceptors> <interceptor name="myInterceptor" class="org.tool.MyInterceptor"></interceptor> </interceptors> <default-interceptor-ref name=""></default-interceptor-ref> <action name="struts" class="org.action.StrutsAction"> <result name="success">/welcome.jsp</result> <result name="error">/hello.jsp</result> <result name="input">/hello.jsp</result> <!--拦截配置在result后面 --> <!--使用系统默认拦截器栈 --> <interceptor-ref name="defaultStack"></interceptor-ref> <!--配置拦截器 --> <interceptor-ref name="myInterceptor"></interceptor-ref> </action> </package> </struts>
备注
改成 "http://struts.apache.org/dtds/struts-2.1.dtd"就可以了,原因未知。
经过这样简单的配置后,重新部署项目,在运行界面输入“hello”,也会经过拦截返回到当前页面,如图3.11、图3.12所示。
图3.11 运行界面
图3.12 提交后返回当前页面