Struts2 中拦截器配置一般都是在 struts.xml 配置文件中。笔者自己编写三个拦截器类,通过在 struts.xml 配置文件中定义,查看运行效果,介绍自定义拦截器的执行顺序和配置文件中遵行的配置原理。
4.3.1 扩展拦截器接 口的自定义拦截器配置
技术要点
本节代码介绍拦截器基础配置以及设置参数功能。
= 配置文件 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"
class="com.example.struts.interceptor.ExampleInterceptor">
<!-- 参数设置 -->
<param name="newParam">test</param>
</interceptor>
</interceptors>
<!-- Action 名字,类以及导航页面定义 -->
<!-- 通过 Action 类处理才导航的的 Action 定义 -->
<action name="Login"
class="com.example.struts.action.LoginAction" >
<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 成功。
4.3.2 继承抽象拦截器的自定义拦截器配置
技术要点
本节代码介绍抽象拦截器配置并对缺省拦截器栈做简单介绍。
= 继承抽象拦截器类的自定义拦截器类编写方式。
= 配置文件 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"
class="com.example.struts.interceptor.ExampleInterceptor">
</interceptor>
<!--
拦截器栈配置定义
<interceptor-stack name="exampleStack">
<interceptor-ref name="example"></interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
</interceptor-stack>
-->
</interceptors>
<action name="Login"
class="com.example.struts.action.LoginAction">
<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"
class="com.example.struts.action.LoginAction">
<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 ”的拦截器都已经执行。
4.3.3 继承方法拦截器的自定义拦截器配置
技术要点
本节代码介绍方法拦截器配置并对缺省拦截器栈对整个 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"
class="com.example.struts.interceptor.ExampleInterceptor">
</interceptor>
</interceptors>
<!--
缺省拦截器栈配置定义
<default-interceptor-ref name="example"></default-interceptor-ref>
-->
<!-- Action 名字,类以及导航页面定义 -->
<!-- 通过 Action 类处理才导航的的 Action 定义 -->
<action name="Login"
class="com.example.struts.action.LoginAction" method="method" >
<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