struts2拦截器原理:
当请求action时,struts2会查找配置文件,并根据配置实例化相对的 拦截器对象,然后串成一个列表,然后一个一个的调用列表中的拦截器。
比如:某些页面必须登录才可以访问,可以在每个action执行处理逻辑之前先判断是否已登录,但这种做法不利于代码复用,所以将这些检查是否登录的代码放到拦截器中进行。
自定义拦截器:
自定义拦截器首先要实现com.opensymphony.xwork2.interceptor.Interceptor接口,该接口有三个方法,init、destroy、intercept方法。
init():在服务器启动时加载一次,并且只加载一次。
destroy():当拦截器销毁时执行的方法。
Interceptor():拦截器核心方法,其中有一个参数actionInvocation。
actionInvocation.invoke()是如果只有一个拦截器执行完这个方法后,会返回给视图,如果有多个拦截器,它顺序的执行完所有的拦截器再返回给视图,也就是调用后面的action继续执行。
创建拦截器:
package com.struts2.web; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.Interceptor; //第一种创建方式 实现com.opensymphony.xwork2.interceptor.Interceptor接口 //拦截器生命周期:随着项目启动而创建,项目关闭而销毁 public class MyInterceptor implements Interceptor { @Override //初始化 public void init() { } @Override //核心拦截方法 public String intercept(ActionInvocation actionInvocation) throws Exception { return actionInvocation.invoke(); } @Override //销毁 public void destroy() { } }
package com.struts2.web; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.AbstractInterceptor; //第二种方式:继承com.opensymphony.xwork2.interceptor.AbstractInterceptor类 public class MyInterceptor2 extends AbstractInterceptor { @Override //直接实现拦截方法 public String intercept(ActionInvocation actionInvocation) throws Exception { return actionInvocation.invoke(); } }
package com.struts2.web; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor; //第三种方式:继承com.opensymphony.xwork2.interceptor.MethodFilterInterceptor类 public class MyInterceptor3 extends MethodFilterInterceptor { @Override protected String doIntercept(ActionInvocation actionInvocation) throws Exception { //前处理 actionInvocation.invoke(); //放行 //后处理 return null; } }
第三种方式 MethodFilterInterceptor是继承了第二种方式的AbstractInterceptor类 第二种方式实现了第一种方式的Interceptor接口。
拦截器API
放行:actionInvocation.invoke();
前处理:放行前代码
后处理:放行后代码
不放行直接跳转到结果页面:return "success" 返回一个字符串,不执行后续的拦截器以及action。直接跳转到一个页面
拦截器配置
<package name="inter" namespace="/" extends="struts-default"> <interceptors> <!--注册拦截器--> <interceptor name="MyInterceptor3" class="com.struts2.web.MyInterceptor3"></interceptor> <!--注册拦截器栈 --> <interceptor-stack name="myStack"> <!--加入自定义的拦截器 --> <interceptor-ref name="MyInterceptor3"></interceptor-ref> <!--引用默认的拦截器栈(20个)--> <interceptor-ref name="defaultStack"></interceptor-ref> </interceptor-stack> </interceptors> <!--指定包中的默认拦截器栈 --> <default-interceptor-ref name="myStack"></default-interceptor-ref> <action name="Demo1Action" class="com.struts2.web.Demo1Action" method="execute"> <result name="success">/demo1.jsp</result> </action> </package>
此时执行包中的action就会走拦截器的前处理 放行到action处理 最后后处理
指定方法调用拦截器
修改demo1 为多个方法的
public class Demo1Action extends ActionSupport { public String execute(){ System.out.println("Demo1 Action execute"); return SUCCESS; } public String register(){ System.out.println("Demo1 Action register"); return SUCCESS; } public String login(){ System.out.println("Demo1 Action login"); return SUCCESS; } }
修改配置文件支持动态方法
<package name="inter" namespace="/" extends="struts-default"> <interceptors> <interceptor name="MyInterceptor3" class="com.struts2.web.MyInterceptor3"></interceptor> <interceptor-stack name="myStack"> <interceptor-ref name="MyInterceptor3"></interceptor-ref> <interceptor-ref name="defaultStack"></interceptor-ref> </interceptor-stack> </interceptors> <default-interceptor-ref name="myStack"></default-interceptor-ref> <global-allowed-methods>execute,login,register</global-allowed-methods> <action name="Demo1Action_*" class="com.struts2.web.Demo1Action" method="{1}"> <result name="success">/demo1.jsp</result> </action> </package>
此时访问三个方法都是走拦截器的,修改配置文件如下
<package name="inter" namespace="/" extends="struts-default"> <interceptors> <interceptor name="MyInterceptor3" class="com.struts2.web.MyInterceptor3"></interceptor> <interceptor-stack name="myStack"> <interceptor-ref name="MyInterceptor3"> <!--指定哪些方法不拦截--> <param name="excludeMethods">login,register</param> </interceptor-ref> <interceptor-ref name="defaultStack"></interceptor-ref> </interceptor-stack> </interceptors> <default-interceptor-ref name="myStack"></default-interceptor-ref> <global-allowed-methods>execute,login,register</global-allowed-methods> <action name="Demo1Action_*" class="com.struts2.web.Demo1Action" method="{1}"> <result name="success">/demo1.jsp</result> </action> </package>
然后访问 login、register都不走自定义的拦截器了 includeMethods 哪些拦截 excludeMethods哪些方法不拦截 只可设置一种
实现登陆拦截器
public class MyInterceptor3 extends MethodFilterInterceptor { @Override protected String doIntercept(ActionInvocation actionInvocation) throws Exception { Map<String, Object> session = ActionContext.getContext().getSession(); Object user = session.get("user"); //已登陆 放行 if(user != null){ return actionInvocation.invoke(); }else{ //没登陆 去登陆页面 return "toLogin"; } } }
全局配置结果集
<package name="inter" namespace="/" extends="struts-default"> <interceptors> <interceptor name="MyInterceptor3" class="com.struts2.web.MyInterceptor3"></interceptor> <interceptor-stack name="myStack"> <interceptor-ref name="MyInterceptor3"> <param name="excludeMethods">login,register</param> </interceptor-ref> <interceptor-ref name="defaultStack"></interceptor-ref> </interceptor-stack> </interceptors> <default-interceptor-ref name="myStack"></default-interceptor-ref> <!--定义全局结果集 --> <global-results> <result name="toLogin" type="redirect">login.jsp</result> </global-results> <global-allowed-methods>execute,login,register</global-allowed-methods> <action name="Demo1Action_*" class="com.struts2.web.Demo1Action" method="{1}"> <result name="success">/demo1.jsp</result> </action> </package>
登陆代码
ActionContext.getContext().getSession().put("user","name");
前台 访问execute 自动跳转到登陆页面 登陆后 在访问execute 正常