Struts2教程 - 4.3 在Struts2中配置自定义的拦截器
Struts2中拦截器配置一般都是在struts.xml配置文件中。笔者自己编写三个拦截器类,通过在struts.xml配置文件中定义,查看运行效果,介绍自定义拦截器的执行顺序和配置文件中遵行的配置原理。
本节代码介绍拦截器基础配置以及设置参数功能。
=???配置文件struts.xml中如何定义拦截器。
=???Action配置中拦截器参数定义和注意点。
=???拦截器参数的设置和配置修改过程。
<!-------------------------------------------文件名:ExampleInterceptor.java-------------------------------->
import?com.opensymphony.xwork2.ActionInvocation;
import?com.opensymphony.xwork2.interceptor.Interceptor;
?
public?class ExampleInterceptor implements Interceptor {
//设置新参数
private String newParam;
?
public String getNewParam() {
?????????? return newParam;
}
?
public void setNewParam(String newParam) {
?????????? this.newParam = newParam;
}
?
public void destroy() {
?????????? System.out.println("end doing...");
}
?
//拦截器初始方法
public void init() {
?????????? System.out.println("start doing...");
?????????? System.out.println("newParam is:"+newParam);
?
}
?
//拦截器拦截方法
public String intercept(ActionInvocation arg0) throws Exception {
?????????? System.out.println("start invoking...");
?????????? String result = arg0.invoke();
?????????? System.out.println("end invoking...");
?????????? return result;
}
?
}
拦截器映射配置。
<!-------------------------------------------文件名:struts.xml-------------------------------->
<!--?拦截器配置定义?-->
?????????? <interceptors>??????????
??????????????????? <interceptor name="example"
???????????????????????????? style="text-align: justify; line-height: 13pt; background-color: #e0e0e0; font-size: 9pt; color: #000000; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; white-space: normal; text-indent: 18pt;">???????????????????????????? <!--?参数设置?-->
???????????????????????????? <param name="newParam">test</param>
??????????????????? </interceptor>
?????????? </interceptors>
?????????? <!-- Action名字,类以及导航页面定义?-->
?????????? <!--?通过Action类处理才导航的的Action定义?-->
?????????? <action name="Login"
??????????????????? >
??????????????????? <result name="input">/jsp/login.jsp</result>
??????????????????? <result name="success">/jsp/success.jsp</result>
??????????????????? <!-- Action中拦截器定义?-->
??????????????????? <interceptor-ref name="example">
??????????????????? <!--?改变拦截器参数值?-->
???????????????????????????? <param name="newParam">example</param>
??????????????????? </interceptor-ref>
?????????? </action>
执行效果如图4.2所示。
图4.2??执行拦截器后效果
参数值显示如图4.3所示。
图4.3? newParam参数值显示图
(1)先看struts.xml文件,在文件开始以<interceptors>开头,</interceptors>结尾形式定义了拦截器,该拦截器命名为example,映射的类文件路径写在class属性中。在<Action>中<result>标签后,可以定义只在该Action执行时候会拦截的拦截器定义,其实就是调用在<Action>前定义的example拦截器。并且还可以以<param>标签定义拦截器属性。
(2)<param>标签定义拦截器属性,或者称为参数。param其实就是英语中参数缩写形式。name是参数名,而在<param></param>间的内容就是该定义的参数值。
注意:如果在<Action>中和<Action>外都定义<param>的值,比如在本实例中<Action>中newParam值为“example”,<Action>外newParam值为“test”。而在运行时候显示的还是<Action>中的参数值,即“example”。显示如图4.3。可以理解为屏蔽了<Action>外参数值,因此如果定义多个Action,每个Action都调用了example拦截器,则都可以自定义自己的newParam的值了。如果不定义的话,那显示的就是“test”,否则就是各自定义的newParam值。
(3)再来看看ExampleInterceptor类代码,newParam是它的一个私有变量属性,有自己的setter、getter方法。而且它扩展了Interceptor接口,该接口是Struts2的类库中自带的接口类。重写interceptor方法,用invoke方法执行Action,在Action前后执行两个打印方法。
启动服务器后,在网页上显示登录页面,单击“登录”,然后在MyEclipse的控制台下就可以看见如图4.2显示的效果图。如果读者能看见这两行字被打印出来,就说明example拦截器拦截Login Action成功。
本节代码介绍抽象拦截器配置并对缺省拦截器栈做简单介绍。
=???继承抽象拦截器类的自定义拦截器类编写方式。
=???配置文件struts.xml中如何定义缺省拦截器。
<!-------------------------------------------文件名:ExampleInterceptor.java-------------------------------->
import?com.opensymphony.xwork2.ActionInvocation;
import?com.opensymphony.xwork2.interceptor.AbstractInterceptor;
?
public?class ExampleInterceptor extends AbstractInterceptor {
?
//重写抽象拦截器的拦截方法
@Override
public String intercept(ActionInvocation arg0) throws Exception {
?????????? System.out.println("start invoking2...");
?????????? String result =arg0.invoke();
?????????? System.out.println("end invoking2...");
?????????? return result;
}
}
拦截器映射配置。
<!-------------------------------------------文件名:struts.xml-------------------------------->
<struts>
<!-- Action所在包定义?-->
<package name="C04.3.2" extends="struts-default">
<!--?拦截器配置定义?-->
?????????? <interceptors>
??????????????????? <interceptor name="example"
???????????????????????????? style="text-align: justify; line-height: 13pt; background-color: #e0e0e0; font-size: 9pt; color: #000000; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; white-space: normal; text-indent: 18pt;">??????????????????? </interceptor>
??????????????????? <!--?
?????????????????????????????拦截器栈配置定义
???????????????????????????? <interceptor-stack name="exampleStack">
???????????????????????????? <interceptor-ref name="example"></interceptor-ref>
???????????????????????????? <interceptor-ref name="defaultStack"></interceptor-ref>
???????????????????????????? </interceptor-stack>
??????????????????? -->
?????????? </interceptors>
?????????? <action name="Login"
??????????????????? style="text-align: justify; line-height: 13pt; background-color: #e0e0e0; font-size: 9pt; color: #000000; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; white-space: normal; text-indent: 18pt;">??????????????????? <result name="input">/jsp/login.jsp</result>
??????????????????? <result name="success">/jsp/success.jsp</result>
??????????????????? <!-- Action拦截器配置定义?-->
??????????????????? <interceptor-ref name="example"></interceptor-ref>
??????????????????? <!-- Action拦截器栈配置定义?-->
??????????????????? <interceptor-ref name="defaultStack"></interceptor-ref>
?????????? </action>
</package>
</struts>
拦截器执行效果如图4.4所示。
图4.4??执行拦截器后效果
拦截器栈执行效果如图4.5所示。
?
图4.5??缺省拦截器栈中包含的校验拦截器执行
(1)ExampleInterceptor类中,继承AbstractInterceptor抽象类。读者可以查看struts2的源代码,在AbstractInterceptor中只有intercept这一个抽象方法。因此自定义的ExampleInterceptor中只需要对这个方法进行重写。重写内容和4.3.1小节类似。
(2)struts.xml配置文件中,在<Action>前还是如4.3.1定义名为“example”的拦截器。在<Action>中,配置“example”拦截器。
注意:在<Action>中还配置了“defaultStack”拦截器栈,这是因为如果在<Action>中不配置该拦截器栈,则Login.action运行时候只会执行配置的“example”拦截器,不会执行“defaultStack”拦截器栈。而且“defaultStack”是Struts2配置的缺省拦截器栈,在4.1小节中的struts-default.xml中定义的拦截器都是由它来调用执行。Struts2规定如果在<Action>中,开发人员配置了自己定义的拦截器或拦截器栈,不显式在struts.xml配置文件中配置“defaultStack”拦截器栈,则所有struts-default.xml中定义的拦截器都不会执行即不执行“defaultStack”拦截器栈。当然如果在<Action>中开发人员没有配置自己定义的拦截器或拦截器栈,就算不显示配置“defaultStack”拦截器栈,则“defaultStack”拦截器栈是会执行的。
(3)为了让Action被执行时候,“defaultStack”拦截器栈和“example”的拦截器都执行,一种办法是如上代码所示。另一种办法也可以如struts.xml配置文件中被注释的那段自定义的拦截器栈配置。在4.1小节中也说过拦截器栈中可以配置拦截器栈,因此在注释中“defaultStack”拦截器栈可以作为配置的“exampleStack”拦截器栈的子元素。在<Action>中配置代码可以写成如下代码中黑体所示:
<!-------------------------------------------文件名:struts.xml-------------------------------->
?????????? <action name="Login"
?????????????????? style="text-align: justify; line-height: 13pt; background-color: #e0e0e0; font-size: 9pt; color: #000000; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; white-space: normal; text-indent: 18pt;">??????????????????? <result name="input">/jsp/login.jsp</result>
??????????????????? <result name="success">/jsp/success.jsp</result>
??????????????????? <!-- Action拦截器栈配置定义?-->
????????????????????<interceptor-ref name="exampleStack"></interceptor-ref>
?????????? </action>
这样的代码形式也能保证“defaultStack”拦截器栈和“example”的拦截器都执行。例如在登录页面不输入任何登录信息,单击“登录”按钮。在MyEclipse的控制台下,执行结果如图4.4所示。而在页面中显示如图4.5,“defaultStack”拦截器栈中包含的输入校验拦截器执行,显示拦截后的信息。这两张图就充分证明了“defaultStack”拦截器栈和“example”的拦截器都已经执行。
本节代码介绍方法拦截器配置并对缺省拦截器栈对整个Web项目的Action影响进行介绍。
=???继承方法拦截器类的自定义拦截器类编写方式。
=???配置文件struts.xml中如何定义方法拦截器和其属性。
=???对所有Action配置拦截器和拦截器栈。
<!-------------------------------------------文件名:ExampleInterceptor.java-------------------------------->
import?com.opensymphony.xwork2.ActionInvocation;
import?com.opensymphony.xwork2.interceptor.MethodFilterInterceptor;
?
public?class ExampleInterceptor extends MethodFilterInterceptor {
//重写方法拦截器拦截方法
@Override
protected String doIntercept(ActionInvocation arg0) throws Exception {
?????????? System.out.println("start invoking3...");
?????????? String result = arg0.invoke();
?????????? System.out.println("end invoking3...");
?????????? return result;
}
LoginAction中增加了method方法
<!-------------------------------------------文件名:LoginAction.java-------------------------------->
public?String method()throws Exception {
???????????FORWARD?= "success";
?????????? return?FORWARD;
}
拦截器映射配置。
<!-------------------------------------------文件名:struts.xml-------------------------------->
<struts>
<!-- Action所在包定义?-->
<package name="C04.3" extends="struts-default">
<!--?拦截器配置定义?-->
?????????? <interceptors>
??????????????????? <interceptor name="example"
???????????????????????????? style="text-align: justify; line-height: 13pt; background-color: #e0e0e0; font-size: 9pt; color: #000000; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; white-space: normal; text-indent: 18pt;">??????????????????? </interceptor>
?????????? </interceptors>
?????????? <!--?
????????????????????缺省拦截器栈配置定义
??????????????????? <default-interceptor-ref name="example"></default-interceptor-ref>
?????????? -->
?????????? <!-- Action名字,类以及导航页面定义?-->
?????????? <!--?通过Action类处理才导航的的Action定义?-->
?????????? <action name="Login"
??????????????????? style="text-align: justify; line-height: 13pt; background-color: #e0e0e0; font-size: 9pt; color: #000000; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; white-space: normal; text-indent: 18pt;">??????????????????? <result name="input">/jsp/login.jsp</result>
??????????????????? <result name="success">/jsp/success.jsp</result>
??????????????????? <!-- Action方法拦截器配置定义?-->
??????????????????? <interceptor-ref name="example">
???????????????????????????? <!--?被拦截方法配置定义?-->
???????????????????????????? <param name="includeMethods">method</param>
???????????????????????????? <!--?不被拦截方法配置定义?-->
???????????????????????????? <param name="excludeMethods">method,execute</param>
??????????????????? </interceptor-ref>
?????????? </action>
</package>
</struts>
“includeMethods”配置后的拦截器执行效果如图4.6所示。
?
图4.6??执行方法拦截器后效果
“includeMethods”和“excludeMethods”同时配置后的拦截器执行效果如图.7所示。
?
图4.7? method方法还是被拦截器拦截
(1)ExampleInterceptor类中,继承MethodFilterInterceptor抽象类。读者也可以查看struts2的源代码,在MethodFilterInterceptor中也只有一个抽象方法,但该抽象方法名为“doIntercept”。也对这个方法进行重写。重写内容和4.3.1小节类似。
(2)LoginAction.java中又定义了一个名为“method”方法,在struts.xml配置文件中,因为LoginAction中有execute方法,又有method方法,因此在<Action>中,请读者注意struts.xml中黑体部分,该部分代码表示现在LoginAction只执行method方法,而execute方法不被执行。笔者在<Action>中增加了一个“method”属性,该属性中“=”后面的内容是Action中具体方法名,如果不写“method”属性,Action是缺省执行execute方法。如果写了“method”属性,Action就执行“=”后写的具体方法。而不会执行execute方法。“example”拦截器还是如之前在<Action>前定义。在<Action>中配置“example”拦截器,笔者增加了“includeMethods”和“excludeMethods”两个param属性定义。“includeMethods”表示的是被拦截器拦截的方法。方法名写在<param>和</param>之间,如果有多个方法开发人员需要拦截器拦截,则方法名之间以“,”相隔。“excludeMethods”表示的是不被拦截器拦截的方法。如果有多个方法,也是以“,”相隔。
注意:如struts.xml配置文件中代码所示。假设
<param name="excludeMethods">method,execute</param>
这行代码被注释,则运行后在MyEclipse的控制台中看见是如图4.6的运行后效果。这说明method方法被拦截。如果
<param name="includeMethods">method</param>
这行代码被注释,则MyEclipse的控制台中是没有任何拦截器拦截信息显示。说明method没有被拦截器拦截即拦截器没有执行。
但是如struts.xml配置文件中代码显示,上述两行代码都没有被注释,读者有时候会不知道method方法到底是被拦截器拦截还是不被拦截。其实运行后的效果如图4.7所示。这说明method方法在两个属性中都被定义,Struts2认为method方法还是被拦截的。
(3)请读者注意struts.xml配置文件中,<Action>前被注释的<default-interceptor-ref >定义。该标签表示的是所有Action都会执行的拦截器或拦截器栈的定义。之前的代码中对于拦截器的定义是在<Action>前,拦截器的配置都是在<Action>中,比如“example”拦截器只有在LoginAction执行时候才会去拦截。如果是配置<default-interceptor-ref >中,则不管是LoginAction还是其他struts.xml配置文件中定义的Action都会被“example”拦截。在<default-interceptor-ref >中,也可以配置拦截器栈。如4.3.2小节中的“exampleStack”拦截器栈如果在<default-interceptor-ref >中配置,则所有Action执行时候,“exampleStack”拦截器栈都会执行该栈中包含的拦截器。
注意:struts.xml配置文件中要么没有<default-interceptor-ref >定义,如果定义了也只能定义一次。该标签在struts.xml配置文件中只能写在<Action>前,而且只能写一次。不能重复定义它。
更多信息请查看?java进阶网?http://www.javady.com/index.php/category/thread