拦截器用于定义Action中重复执行的动作,从而提供更好的代码重用,拦截器基于AOP(面向切面编程)的原理,从而实现了与Action的解耦。
拦截器配置
Struts 2拦截器是在struts.xml中定义的。
定义拦截器:
<interceptor name=”拦截器名称” class=”拦截器实现类”>
<param name=”参数名”>参数值</param> // 配置拦截器默认参数值
</interceptor>
定义拦截器栈:
<interceptor-stack name=”拦截器栈名”>
<interceptor-ref name=”拦截器名1” />
<interceptor-ref name=”拦截器名2”>
<param name=”参数名”>参数值</param> // 引用拦截器时覆盖默认参数值
</interceptor-ref>
<interceptor-ref name=”拦截器栈名” /> // 拦截器栈中可以引用拦截器栈
… …
</interceptor-stack>
使用拦截器:
<action name=”Action名” class=”Action实现类”>
<result name=”视图名”>视图资源</result> // 视图定义
… …
<interceptor-ref name=”defaultStack” /> // 显示引用默认拦截器栈
<interceptor-ref name=”拦截器名或拦截器栈名”>
<param name=”参数名”>参数值</param> // 引用拦截器时覆盖默认参数值
</interceptor-ref>
… …
</action>
默认拦截器:
可以为一个包配置默认拦截器栈:
<package name=”包名”>
<interceptors>
<interceptor …/> // 拦截器定义
<interceptor-stack …/> // 拦截器栈定义
</interceptors>
<default-interceptor-ref name=”拦截器名或拦截器栈名” /> // 设置默认拦截器
<action … />
</package>
当包继承struts-default包时将默认使用defaultStack拦截器栈。
自定义拦截器
1、 实现Interceptor接口:
public interface Interceptor extends Serializable {
void destroy(); // 销毁该拦截器之前的回调方法
void init(); // 初始化该拦截器的回调方法
String intercept(ActionInvocation invocation) throws Exception; // 拦截方法,返回视图名
}
2、 继承AbstractInterceptor类,该类提供了init和destroy方法的空实现,只需要实现intercept方法。
3、 方法过滤拦截器,继承MethodFilterInterceptor,实现doIntercept方法,在配置文件中配置includeMethods和excludeMethods参数值。
includeMethods:设置被拦截的方法,多个方法用逗号分隔;
excludemethods:设置不被拦截的方法,多个方法用逗号分隔。
注:当某个方法既设置在了includeMethods里又设置在了excludemethods里时,该方法将被拦截。
拦截器的执行顺序
当有多个拦截器执行拦截时,以Action的execute方法作为分界,在该方法之前执行的拦截器按照从上到下的引用顺序执行,之后执行的拦截器按照引用倒序执行,举例说明:
拦截器类:
public class MyInterceptor extends AbstractInterceptor {
private String name;
@Override
public String intercept(ActionInvocation invocation) throws Exception {
System.out.println("interceptor : " + getName() + "before execute");
String result = invocation.invoke();
System.out.println("interceptor : " + getName() + "after execute");
return result;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
定义拦截器:
<interceptors>
<interceptor name="myInterceptor" class="ssf.interceptors.MyInterceptor">
<param name="name">My Interceptor</param>
</interceptor>
</interceptors>
<action name="welcome" class="welcomeAction">
<result type="tiles">welcome</result>
<interceptor-ref name="defaultStack" />
<interceptor-ref name="myInterceptor">
<param name="name">First Interceptor</param>
</interceptor-ref>
<interceptor-ref name="myInterceptor">
<param name="name">Second Interceptor</param>
</interceptor-ref>
</action>
输出结果:
interceptor : First Interceptorbefore execute
interceptor : Second Interceptorbefore execute
interceptor : Second Interceptorafter execute
interceptor : First Interceptorafter execute
使用拦截器栈时给栈中的拦截器设置参数值:
<interceptor-ref name=”拦截器栈名”>
<param name=”拦截器一.参数”>拦截器一的参数值</param>
<param name=”拦截器二.参数”>拦截器二的参数值</param>
… …
</interceptor-ref>
Struts 2的内建拦截器
1、 alias:实现在不同请求中相似参数别名的转换;
2、 autowiring:这是个自动装配的拦截器,主要用于当Struts 2和Spring整合时,Struts 2可以使用自动装配的方式来访问Spring容器中的Bean;
3、 chain:构建一个Action链,使当前Action可以访问前一个Action的属性,一般和<result type=”chain” … />一起使用;
4、 conversionError:这是一个负责处理类型转换错误的拦截器,它负责将类型转换错误从ActionContext中取出来,并转换成Action的FieldError错误;
5、 createSession:该拦截器负责创建HttpSession对象,主要用于那些需要HttpSession对象才能工作的拦截器中;
6、 debugging:当使用Struts 2的开发模式中,这个拦截器会提供更多的调试信息;
7、 execAndWait:后台执行Action,负责将等待画面发给用户;
8、 exception:这个拦截器负责处理异常,它将异常映射为结果;
9、 fileUpload:这个拦截器主要负责处理文件上传,它负责解析表单中文件域的内容;
10、 i18n:这是支持国际化的拦截器,它负责把所选的语言、区域放入用户的Session中;
11、 model-driven:这是一个用于模型驱动的拦截器,当某个Action类实现了ModelDriven接口时,它负责把getModel()方法的结果堆入ValueStack中;
12、scoped-model-driven:如果一个Action实现了ScopedModelDriven接口,该拦截器负责从指定生存范围中找出指定的model,并通过setModel()方法将该Model传给Action实例;
13、params:这是最基本的一个拦截器,它负责解析HTTP中的请求参数,并将参数值设置成Action中的属性值;
14、prepare:如果Action实现了Preparable接口,将会调用该拦截器的prepare()方法;
15、static-params:这个拦截器负责将XML中<action>标签下的<param>标签中的参数传入Action;
16、scope:这是范围转换拦截器,它可以将Action的状态信息保存到HttpSession范围或者保存到ServletContext范围;
17、servlet-config:如果某个Action需要访问Servlet API,就是通过这个拦截器实现的;
18、roles:这是一个JAAS拦截器,只有当浏览者取得合适的授权后才能调用被拦截的Action;
19、timer:这个拦截器负责输出Action的执行时间,在分析Action的性能瓶颈时非常有用;
20、token:这个拦截器用于阻止重复提交;
21、token-session:这个拦截器与前一个作用类似,只是把token保存到HttpSession中;
22、validation:通过执行在xxxAction-validation.xml中定义的校验器,从而完成数据校验;
23、workflow:这个拦截器负责调用Action类中的validate方法,如果校验失败,则返回input的逻辑视图;
大部分时候开发者无需配置这些拦截器,应为struts-default.xml文件中已经配置了这些拦截器,只要我们定义的包继承struts-default包,就可以直接使用这些拦截器;
具体参见struts-default.xml中的配置。