——杨波(请勿随意转载)
Struts2设计的灵巧性,在很大程度上得益于拦截器设计,当需要扩展Struts2功能时,只需要提供对应拦截器,并将它配置在Struts2容器中即可;如果不需要该功能时,也只需要取消该拦截器的配置即可。这种可插拔式的设计,正是软件设计领域一直孜孜以求的目标。拦截器几乎完成了Struts2框架70%的工作,包括解析请求参数、将请求参数赋值给Action属性、执行数据校验、文件上传等。
由于struts2拦截器的可插拔设计,有人形象的把拦截器比作抽屉,而struts2只是一个空的容器,正是有了这些抽屉,可以随时插入,又可以随时抽出,struts2的可扩展性和灵活性才得到充分的体现。拦截器的这种机制是按照AOP来设计的,AOP与OOP并不冲突,反而是对OOP的一个很好的完善和补充。
Struts2官网上有这样一幅图,从这张图上可以看出,Struts2 架构的Action被一个或者多个拦截器,或者一个拦截器栈包围着,用户的请求会被这些拦截器所拦截。
刚开始用struts2的时候一直不明白为什么要加上extends="struts-default"这句话,现在终于恍悟,原来struts2中也内建了大量的拦截器,这些拦截器以name-class对的形式配置在struts-default. xml文件中,其中name是拦截器的名字,就是以后使用该拦截器的唯一标识;class则指定了该拦截器的实现类,如果我们定义的package继承了Struts2的默认struts-default包,则可以自由使用下面定义的拦截器,否则必须自己定义这些拦截器。
Interceptor
Name
Description
alias
在不同的请求之间将参数在不同的名字间转换,请求内容不变.
chain
让前面一个Action的属性可以被后一个Action访问
checkbox
Adds automatic checkbox handling code that detect an unchecked checkbox and add it as a parameter with a default (usually 'false') value. Uses a specially named hidden field to detect unsubmitted checkboxes. The default unchecked value is overridable for non-boolean value'd checkboxes.
cookie
使用配置的name、value来设置cookies
conversionError
将错误从ActionContext中添加到Action的属性字段中
createSession
自动地创建HttpSession,用来为需要使用到HttpSession的拦截器服务
debugging
提供不同的调试用的页面来展示内部的数据状况
execAndWait
在后台执行Action,同时将用户带到一个中间的等待页面
exception
将异常定位到一个页面
fileUpload
提供文件上传功能
i18n
记录用户选择的locale
logger
输出Action的名字
store
存储或者访问实现ValidationAware接口的Action类出现的消息、错误、字段错误等。
model-driven
如果一个类实现了ModelDriven,将getModel得到的结果放在ValueStack中
Scoped Model Driven Interceptor
scoped-model-driven
如果一个Action实现了ScopedModelDriven,则这个拦截器会从相应的Scope中取出model,调用Action的setModel方法将其放入Action内部
params
将请求中的参数设置到Action中去
prepare
如果Action实现了Preparable,则该拦截器调用Action类的prepare方法
scope
将Action状态存入Session和Application的简单方法
servletConfig
提供访问HttpServletRequest和HttpServletResponse的方法,以Map的方式访问
staticParams
从struts.xml文件中将<action>中的<param>下的内容设置到对应的Action中
roles
确定用户是否具有JAAS指定的Role,否则不予执行
timer
输出Action执行的时间
token
通过Token来避免双击
tokenSession
和Token Interceptory一样,不过双击的时候把请求的数据存储在Session中
validation
使用action-validation.xml文件中定义的内容校验提交的数据
workflow
调用Action的validate的方法,一旦有错返回,重新定位到INPUT页面
N/A
从参数列表中删除不必要的参数
profiling
通过参数激活profile
当然除了可以使用系统提供的默认的拦截器,我们也可以自定义自己的拦截器。Struts2框架提供了一个定义拦截器的接口Interceptor接口。同时Struts2框架也提供了一个可以用于过滤拦截Action方法的类MethodFilterInterceptor。该类有两个属性excludeMethods和includeMethods。分别代表指定拦截器拒绝拦截的方法和需要拦截的方法。例:
public classFilterInterceptor extends MethodFilterInterceptor{
private String name;
protected String doIntercept(ActionInvocation arg0)throws Exception{
//HelloWorld hw=(HelloWorld)arg0.getAction();
String res=arg0.invoke();
return res;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
再看看struts.xml配置文件
<package name="struts2tutoial"extends="struts-default">
<interceptors>
<interceptor name="MyInterceptor"class="interceptor.MyInterceptor"/>
<interceptor name="FilterInterceptor"class="interceptor.FilterInterceptor"/>
</interceptors>
<actionname="HelloWorld" class="helloWorld">
<result>/helloWorld.jsp</result>
<interceptor-ref name="defaultStack"/>
<interceptor-refname="MyInterceptor"/>
<interceptor-ref name="FilterInterceptor">
<param name="includeMethods">***</param>
<param name="excludeMethods">***</param>
</interceptor-ref>
</action>
</package>
那么struts2拦截器的流程到底是怎样的呢,struts2的官网上也给出了如下这张图片,看过这张图片就应该对struts2拦截器的运行机制明白多了