Struts2 拦截器
Struts2拦截器在访问某个Action方法之前或之后实施拦截,Struts2拦截器是可插拔的,拦截器是AOP(spring会讲到,现在不理会) 的一种实现.
拦截器栈(InterceptorStack): 将拦截器按一定的顺序联结成一条链. 在访问被拦截的方法时,Struts2拦截器链中的拦截器就会按其之前定义的顺序被依次调用.
Interceptor 接口
Struts 会依次调用程序员为某个Action 而注册的每一个拦截器的interecept方法.
每次调用interecept方法时, Struts 会传递一个ActionInvocation接口的实例.
ActionInvocation: 代表一个给定动作的执行状态, 拦截器可以从该类的对象里获得与该动作相关联的Action 对象和Result 对象. 在完成拦截器自己的任务之后, 拦截器将调用ActionInvocation对象的invoke 方法前进到Action 处理流程的下一个环节.
还可以调用ActionInvocation对象的addPreResultListener方法给ActionInvocation对象“挂” 上一个或多个 PreResultListener监听器. 该监听器对象可以在动作执行完毕之后, 开始执行动作结果之前做些事情
AbstractInterceptor类实现了Interceptor 接口. 并为init,destroy 提供了一个空白的实现
自定义拦截器
定义自定义拦截器的步骤
自定义拦截器
在struts.xml 文件中配置自定义的拦截器
要自定义拦截器需要实现com.opensymphony.xwork2.interceptor.Interceptor接口:
public class PermissionInterceptor implements Interceptor {
public void init() {
}
public String intercept(ActionInvocation invocation) throws Exception {
Object o=ActionContext.getContext().getSession().get("user");
if(o!=null){
//调用action中的方法
return invocation.invoke();
}
return "error";
}
public void destroy() {
}
}
在 struts.xml 文件中配置自定义的拦截器
<package name="aop"namespace="/aop" extends="struts-default">
<interceptors>
<!-- 声明拦截器-->
<interceptor name="permissionInterceptor" class="cn.itcast.aop.PermissionInterceptor" />
<!-- 配置拦截器栈-->
<interceptor-stack name="permissionStack">
<interceptor-ref name="defaultStack" />
<interceptor-ref name="permissionInterceptor" />
</interceptor-stack>
</interceptors>
<!-- 覆盖底层的拦截器栈 对包中的所有action都有效 -->
<default-interceptor-ref name="permissionStack"/>
<global-results>
<resultname="error">/aop/error.jsp</result>
</global-results>
<action name="userAction_*" class="cn.itcast.aop.UserAction" method="{1}">
<resultname="save">/aop/success.jsp</result>
<!—只对当前的action有效à
<interceptor-ref name="permissionStack"></interceptor-ref>
</action>
</package>
因为struts2中如文件上传,数据验证,封装请求参数到action等
功能都是由系统默认的defaultStack中的拦截器实现的,所以
我们定义的拦截器需要引用系统默认的defaultStack,这样应用才
可以使用struts2框架提供的众多功能。
如果希望包下的所有action都使用自定义的拦截器,
可以通过<default-interceptor-ref name=“permissionStack”/>
把拦截器定义为默认拦截器。注意:每个包只能指定一个默认拦截器。
另外,一旦我们为该包中的某个action显式指定了某个拦截器,
则默认拦截器不会起作用。
Struts2 自带的拦截器
拦截器 | 名字 | 说明 |
Alias Interceptor | alias | 在不同请求之间将请求参数在不同名字件转换,请求内容不变 |
Chaining Interceptor | chain | 让前一个Action的属性可以被后一个Action访问,现在和chain类型的result()结合使用。 |
Checkbox Interceptor | checkbox | 添加了checkbox自动处理代码,将没有选中的checkbox的内容设定为false,而html默认情况下不提交没有选中的checkbox。 |
Cookies Interceptor | cookies | 使用配置的name,value来是指cookies |
Conversion Error Interceptor | conversionError | 将错误从ActionContext中添加到Action的属性字段中。 |
Create Session Interceptor | createSession | 自动的创建HttpSession,用来为需要使用到HttpSession的拦截器服务。 |
Debugging Interceptor | debugging | 提供不同的调试用的页面来展现内部的数据状况。 |
Execute and Wait Interceptor | execAndWait | 在后台执行Action,同时将用户带到一个中间的等待页面。 |
Exception Interceptor | exception | 将异常定位到一个画面 |
File Upload Interceptor | fileUpload | 提供文件上传功能 |
I18n Interceptor | i18n | 记录用户选择的locale |
Logger Interceptor | logger | 输出Action的名字 |
Message Store Interceptor | store | 存储或者访问实现ValidationAware接口的Action类出现的消息,错误,字段错误等。 |
拦截器 | 名字 | 说明 |
Model Driven Interceptor | model-driven | 如果一个类实现了ModelDriven,将getModel得到的结果放在Value Stack中。 |
Scoped Model Driven | scoped-model-driven | 如果一个Action实现了ScopedModelDriven,则这个拦截器会从相应的Scope中取出model调用Action的setModel方法将其放入Action内部。 |
Parameters Interceptor | params | 将请求中的参数设置到Action中去。 |
Prepare Interceptor | prepare | 如果Acton实现了Preparable,则该拦截器调用Action类的prepare方法。 |
Scope Interceptor | scope | 将Action状态存入session和application的简单方法。 |
Servlet Config Interceptor | servletConfig | 提供访问HttpServletRequest和HttpServletResponse的方法,以Map的方式访问。 |
Static Parameters Interceptor | staticParams | 从struts.xml文件中将中的中的内容设置到对应的Action中。 |
Roles Interceptor | roles | 确定用户是否具有JAAS指定的Role,否则不予执行。 |
Timer Interceptor | timer | 输出Action执行的时间 |
Token Interceptor | token | 通过Token来避免双击 |
Token Session Interceptor | tokenSession | 和Token Interceptor一样,不过双击的时候把请求的数据存储在Session中 |
Validation Interceptor | validation | 使用action-validation.xml文件中定义的内容校验提交的数据。 |
Workflow Interceptor | workflow | 调用Action的validate方法,一旦有错误返回,重新定位到INPUT画面 |
Parameter Filter Interceptor | N/A | 从参数列表中删除不必要的参数 |
Profiling Interceptor | profiling | 通过参数激活profile |
总结
如何自定义拦截器:
* 所有的拦截器都需要实现Interceptor接口或者继承Interceptor接口的扩展实现类
* 要重写init()、intercept()、destroy()方法
* init()是在struts2框架运行时执行,在拦截器的生命周期中只执行一次,可以做必要的内容的初始化工作
* intercept(),是每一次请求就执行一次,做相关处理工作。
* intercept()方法接收一个ActionInvocation接口的实例
* 通过这个接口的实例,可以获取以下内容
:
//cn.itcast.aop.UserAction@15b5783,动作类的对象
System.out.println("invocation.getAction() : "+invocation.getAction());
//cn.itcast.aop.UserAction@15b5783,与invocation.getAction()方法获取的是同一的对象
System.out.println("invocation.getProxy().getAction() : "+invocation.getProxy().getAction());
//userAction_save,自定义配置文件中的action标签的name属性的值
System.out.println("invocation.getProxy().getActionName() : "+invocation.getProxy().getActionName());
//save,对应动作类指定要执行的方法名
System.out.println("invocation.getProxy().getMethod() : "+invocation.getProxy().getMethod());
// /aop,自定义配置文件中的package标签的namespace属性的值
System.out.println("invocation.getProxy().getNamespace() : "+invocation.getProxy().getNamespace());
* destroy()是在拦截器销毁前执行,在拦截器的声明周期中只执行一次。
* 在struts.xml配置文件中,进行注册
* 在配置文件中的package标签下,进行相关配置:
<interceptors>
<!-- 声明自定义的拦截器 -->
<interceptor name="expessionInterceptor" class="cn.itcast.aop.ExpessionInterceptor" />
<!-- 声明自定义拦截器栈 -->
<interceptor-stack name="expessionStack">
<interceptor-ref name="defaultStack"/>
<!-- 配置使用自定义拦截器 -->
<interceptor-ref name="expessionInterceptor"/>
</interceptor-stack>
</interceptors>
<!-- 配置修改struts2框架运行时,默认执行的是自定义拦截器栈 -->
<default-interceptor-ref name="expessionStack" />