Struts2 拦截器
Struts2 拦截器在访问某个 Action 方法之前或之后实施拦截,Struts2 拦截器是可插拔的,拦截器是 AOP(spring会讲到,现在不理会) 的一种实现.
拦截器栈(Interceptor Stack): 将拦截器按一定的顺序联结成一条链. 在访问被拦截的方法时,Struts2拦截器链中的拦截器就会按其之前定义的顺序被依次调用.
Interceptor 接口
每个拦截器都是实现了com.opensymphony.xwork2.interceptor.Interceptor接口的 Java 类:
1 public interface Interceptor extends Serializable { 2 void init(); 3 String intercept(ActionInvocation invocation) throws Exception; 4 void destroy(); 5 }
•init: 该方法将在拦截器被创建后立即被调用, 它在拦截器的生命周期内只被调用一次. 可以在该方法中对相关资源进行必要的初始化
•interecept: 每拦截一个动作请求, 该方法就会被调用一次. 相当于doFilter方法.
•destroy: 该方法将在拦截器被销毁之前被调用, 它在拦截器的生命周期内也只被调用一次.
*Struts 会依次调用程序员为某个 Action 而注册的每一个拦截器的 interecept 方法.
*每次调用 interecept 方法时, Struts 会传递一个 ActionInvocation 接口的实例.
*ActionInvocation: 代表一个给定动作的执行状态, 拦截器可以从该类的对象里获得与该动作相关联的 Action 对象和 Result 对象.
在完成拦截器自己的任务之后, 拦截器将调用 ActionInvocation 对象的 invoke 方法前进到 Action 处理流程的下一个环节.
*还可以调用 ActionInvocation 对象的 addPreResultListener 方法给 ActionInvocation 对象 “挂” 上一个或多个 PreResultListener 监听器.
该监听器对象可以在动作执行完毕之后, 开始执行动作结果之前做些事情
*AbstractInterceptor 类实现了 Interceptor 接口. 并为 init, destroy 提供了一个空白的实现
自定义拦截器
定义自定义拦截器的步骤
•自定义拦截器-要自定义拦截器需要实现com.opensymphony.xwork2.interceptor.Interceptor接口
•在 struts.xml 文件中配置自定义的拦截器
总结:
1 如何自定义拦截器: 2 * 所有的拦截器都需要实现Interceptor接口或者继承Interceptor接口的扩展实现类 3 4 * 要重写init()、intercept()、destroy()方法 5 6 * init()是在struts2框架运行时执行,在拦截器的生命周期中只执行一次,可以做必要的内容的初始化工作 7 8 * intercept(),是每一次请求就执行一次,做相关处理工作。 9 10 * intercept()方法接收一个ActionInvocation接口的实例 11 12 * 通过这个接口的实例,可以获取以下内容 13 : 14 //cn.zengfansheng.aop.UserAction@15b5783,动作类的对象 15 System.out.println("invocation.getAction() : "+invocation.getAction()); 16 17 //cn.zengfansheng.aop.UserAction@15b5783,与invocation.getAction()方法获取的是同一的对象 18 System.out.println("invocation.getProxy().getAction() : "+invocation.getProxy().getAction()); 19 20 //userAction_save,自定义配置文件中的action标签的name属性的值 21 System.out.println("invocation.getProxy().getActionName() : "+invocation.getProxy().getActionName()); 22 23 //save,对应动作类指定要执行的方法名 24 System.out.println("invocation.getProxy().getMethod() : "+invocation.getProxy().getMethod()); 25 26 // /aop,自定义配置文件中的package标签的namespace属性的值 27 System.out.println("invocation.getProxy().getNamespace() : "+invocation.getProxy().getNamespace()); 28 29 * destroy()是在拦截器销毁前执行,在拦截器的声明周期中只执行一次。 30 31 * 在struts.xml配置文件中,进行注册 32 * 在配置文件中的package标签下,进行相关配置: 33 34 <interceptors> 35 <!-- 声明自定义的拦截器 --> 36 <interceptor name="expessionInterceptor" class="cn.zengfansheng.aop.ExpessionInterceptor" /> 37 38 <!-- 声明自定义拦截器栈 --> 39 <interceptor-stack name="expessionStack"> 40 <interceptor-ref name="defaultStack"/> 41 42 <!-- 配置使用自定义拦截器 --> 43 <interceptor-ref name="expessionInterceptor"/> 44 45 </interceptor-stack> 46 </interceptors> 47 48 <!-- 配置修改struts2框架运行时,默认执行的是自定义拦截器栈 --> 49 <default-interceptor-ref name="expessionStack" />
用户登录案例
1、jsp
test.jsp
<%@ page language="java" pageEncoding="utf-8" contentType="text/html; charset=utf-8"%> <%@ taglib uri="/struts-tags" prefix="s"%> <html> <head> <title>My JSP 'index.jsp' starting page</title> </head> <body> 测试拦截器:<br> <a href="${pageContext.request.contextPath}/aop/userAction_save.action">test</a><br> </body> </html>
error.jsp
<%@ page language="java" pageEncoding="utf-8" contentType="text/html; charset=utf-8"%> <%@ taglib uri="/struts-tags" prefix="s"%> <html> <head> <title>My JSP 'index.jsp' starting page</title> </head> <body> 对不起,您没有权限<br> </body> </html>
index.jsp
<%@ page language="java" pageEncoding="utf-8" contentType="text/html; charset=utf-8"%> <%@ taglib uri="/struts-tags" prefix="s"%> <html> <head> <title>My JSP 'index.jsp' starting page</title> </head> <body> 用户登录!!! <% session.setAttribute("user","user"); %> </body> </html>
success.jsp
<%@ page language="java" pageEncoding="utf-8" contentType="text/html; charset=utf-8"%> <%@ taglib uri="/struts-tags" prefix="s"%> <html> <head> <title>My JSP 'index.jsp' starting page</title> </head> <body> 成功!!!!<br> ${id} </body> </html>
2、java
UserAction.java
import com.opensymphony.xwork2.ActionSupport; @SuppressWarnings("serial") public class UserAction extends ActionSupport { public String save() { System.out.println("UserAction******save()"); return "success"; } }
ExpessionInterceptor.java
import java.util.Map; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.Interceptor; @SuppressWarnings("serial") public class ExpessionInterceptor implements Interceptor { public void init() { System.out.println("ExpessionInterceptor ********* init()"); } public String intercept(ActionInvocation invocation) throws Exception { System.out.println("ExpessionInterceptor ********* intercept()"); //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()); //null 返回结果 System.out.println("invocation.getResult() : "+invocation.getResult()); Map sessionMap = ServletActionContext.getContext().getSession(); Object obj = sessionMap.get("user"); if(obj==null||obj.equals("")){ return "error"; }else{ return "success"; } } public void destroy() { System.out.println("ExpessionInterceptor ********* destroy()"); } }
3、xml
struts_aop.xml
<?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="aop" namespace="/aop" extends="struts-default"> <interceptors> <!-- 声明自定义的拦截器 --> <interceptor name="expessionInterceptor" class="cn.zengfansheng.struts.aop.ExpessionInterceptor" /> <!-- 声明自定义拦截器栈 --> <interceptor-stack name="expessionStack"> <interceptor-ref name="defaultStack"/> <!-- 配置使用自定义拦截器 --> <interceptor-ref name="expessionInterceptor"/> </interceptor-stack> </interceptors> <!-- 配置修改struts2框架运行时,默认执行的是自定义拦截器栈 --> <default-interceptor-ref name="expessionStack" /> <action name="userAction_save" class="cn.zengfansheng.aop.UserAction" method="save"> <result name="success">/aop/success.jsp</result> <result name="error">/aop/error.jsp</result> </action> </package> </struts>
struts.xml
<include file="cn/zengfansheng/struts/aop/struts_aop.xml"></include>