拦截器
要使用拦截器,首先要对它进行配置。拦截器的配置是在 struts.xml 文件中完成的,它通常以 <interceptor> 标签开头,以 </interceptor> 标签结束。定义拦截器的语法格式如下所示:
<interceptor name="interceptorName" class="interceptorClass">
<param name="paramName">paramValue</param>
</interceptor>
上述语法格式中,<interceptor> 元素的 name 属性用于指定拦截器的名称,class 属性用于指定拦截器的实现类。有时,在定义拦截器时需要传入参数,这时需要使用 <param> 标签,其中 name 属性用于指定参数的名称,paramValue 表示参数的值。
拦截器栈
在实际的项目开发中,经常需要在 Action 执行之前执行多个拦截动作,如登录日志记录、权限管理等。
为了方便代码管理和程序的执行,开发者通常会将这些拦截器组成一个拦截器栈,在使用时,可以将栈内的多个拦截器当成一个整体引用。当拦截器栈被附加到一个 Action 上时,在执行 Action 之前必须先执行拦截器栈中的每一个拦截器。
定义拦截器栈使用 <\interceptors> 元素和 <\interceptor-stack> 子元素,当配置多个拦截器时,需要使用 <\interceptor-ref> 元素指定多个拦截器,配置语法如下所示:
<interceptors>
<interceptor-stack name="interceptorStackName">
<interceptor-ref name="interceptorName"/>
...
</interceptor-stack>
</interceptors>
在上述语法中,interceptorStackName 值表示配置的拦截器栈的名称;interceptorName 值表示拦截器的名称。除此之外,在一个拦截器栈中还可以包含另一个拦截器栈,示例代码如下所示:
<package name="default" namespace="/" extends="struts-default">
<!--声明拦截器-->
<interceptors>
<interceptor name="interceptor1" class="interceptorClass"/>
<interceptor name="interceptor2" class="interceptorClass"/>
<!--定义一个拦截器栈myStack,该拦截器栈中包含两个拦截器和一个拦截器栈-->
<interceptor-stack name="myStack">
<interceptor-ref name="defaultStack"/>
<interceptor-ref name="interceptor1"/>
<interceptor-ref name="interceptor2"/>
</interceptor-stack>
</interceptors>
</package>
在上述代码中,定义的拦截器栈的名称是 myStack,在 myStack 栈中,除了引用了两个自定义的拦截器 interceptor1 和 interceptor2 以外,还引用了一个内置拦截器栈 defaultStack,这个拦截器是必须要引入的。
默认拦截器
如果想对一个包下的 Action 使用相同的拦截器,则需要为该包中的每个 Action 都重复指定同一个拦截器,这样写显然过于繁琐。为了解决此问题,Struts2 中支持使用默认拦截器,它可以对其指定的包中的所有 Action 都起到拦截作用。
一旦为某一个包指定了默认拦截器,并且该包中的 Action 未显示指定拦截器,则会使用默认拦截器。反之,若此包中的 Action 显示的指定了某个拦截器,则该默认拦截器将会被屏蔽。此时,如果还想使用默认拦截器,则需要用户手动配置该默认拦截器的引用。
配置默认拦截器需要使用 元素,此元素为 元素的子元素。其语法格式如下所示:
<default-interceptor-ref name="拦截器(栈)的名称"/>
在上述语法格式中,name 属性的值必须是已经存在的拦截器或拦截器栈的名称。下面用该语法格式配置一个默认拦截器,示例代码如下所示:
<package name="default" namespace="/" extends="struts-default">
<!--声明拦截器-->
<interceptors>
<interceptor name="interceptor1" class="interceptorClass"/>
<interceptor name="interceptor2" class="interceptorClass"/>
<!--定义一个拦截器栈myStack,该拦截器栈中包含两个拦截器和一个拦截器栈-->
<interceptor-stack name="myStack">
<interceptor-ref name="defaultStack"/>
<interceptor-ref name="interceptor1"/>
<interceptor-ref name="interceptor2"/>
</interceptor-stack>
</interceptors>
<!--配置包下的默认拦截器,既可以是拦截器,也可以是拦截器栈-->
<default-interceptor-ref name="myStack"/>
<action name="login" class="com.mengma.action.LoginAction">
<result name="input">/login.jsp</result>
</action>
</package>
在上述代码中,指定了包下面的默认拦截器为一个拦截器栈,该拦截器栈将会作用于包下所有的 Action。
注意:每一个包下只能定义一个默认拦截器,如果需要多个拦截器作为默认拦截器,则可以将这些拦截器定义为一个拦截器栈,再将这个拦截器栈作为默认拦截器即可。
完整示例
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<package name="inter" namespace="/" extends="struts-default" >
<interceptors>
<!-- 1.注册拦截器 -->
<interceptor name="myInter3" class="cn.itcast.a_interceptor.MyInterceptor3"></interceptor>
<!-- 2.注册拦截器栈 -->
<interceptor-stack name="myStack">
<!-- 自定义拦截器引入(建议放在20个拦截器之前) -->
<interceptor-ref name="myInter3">
<!-- 指定哪些方法不拦截
<param name="excludeMethods">add,delete</param> -->
<!-- 指定哪些方法需要拦截 -->
<param name="includeMethods">add,delete</param>
</interceptor-ref>
<!-- 引用默认的拦截器栈(20个) -->
<interceptor-ref name="defaultStack"></interceptor-ref>
</interceptor-stack>
</interceptors>
<!-- 3.指定包中的默认拦截器栈 -->
<default-interceptor-ref name="myStack"></default-interceptor-ref>
<action name="Demo1Action_*" class="cn.itcast.a_interceptor.Demo1Action" method="{1}" >
<!-- 为Action单独指定走哪个拦截器(栈)
<interceptor-ref name="myStack"></interceptor-ref>-->
<result name="success" type="dispatcher" >/index.jsp</result>
</action>
</package>
<package name="tag" namespace="/" extends="struts-default" >
<action name="Demo2Action" class="cn.itcast.b_tag.Demo2Action" method="execute" >
<result name="success" type="dispatcher" >/tag1.jsp</result>
</action>
<action name="Demo3Action" class="cn.itcast.b_tag.Demo3Action" method="execute" >
<result name="success" type="dispatcher" >/tag2.jsp</result>
</action>
</package>
</struts>