前面我们了解了拦截器的概念,现在我们来学习如何自定义拦截器并使用。
如何自定义拦截器?
每个拦截器都是实现了interceptor或者继承了interceptor的实现类。
interceptor接口:
init
destory
interceptor
分别对应过滤器的init,destory,doFilter方法
interceptor的返回值指向一个结果类型对应地址,不过只有在未invocation.invoke才有效
invocation参数对应过滤器的chain参数,执行invocation.invoke()表示这个拦截器放行,执行下一个拦截器或者执行action,最后返回action该方法的返回值,跳转到指定结果页面。
声明拦截器例子:
package cn.itcast.aop; import java.util.Map; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.Interceptor; public class ExpressionInterceptor implements Interceptor { public void destroy() { System.out.println("ExpressionInterceptor *********** destory"); } public void init() { System.out.println("ExpressionInterceptor *********** init"); } public String intercept(ActionInvocation invocation) throws Exception { invocation.invoke(); System.out.println("invocation.getAction() : "+invocation.getAction()); System.out.println("invocation.getProxy().getAction() : "+invocation.getProxy().getAction()); System.out.println("invocation.getProxy().getActionName() : "+invocation.getProxy().getActionName()); System.out.println("invocation.getProxy().getMethod() : "+invocation.getProxy().getMethod()); System.out.println("invocation.getProxy().getNamespace( : "+invocation.getProxy().getNamespace()); System.out.println("invocation.getResult() : "+invocation.getResult()); Map sessionMap=ServletActionContext.getContext().getSession(); Object obj=sessionMap.get("user"); if(obj==null || obj.equals("")){ return "error"; } return "success"; } }
在拦截器里面,我们可以通过invoke参数获取一些信息:
如:Action,Action名,执行的方法,方法的返回值,命名空间等:
System.out.println("invocation.getAction() : "+invocation.getAction()); System.out.println("invocation.getProxy().getAction() : "+invocation.getProxy().getAction()); System.out.println("invocation.getProxy().getActionName() : "+invocation.getProxy().getActionName()); System.out.println("invocation.getProxy().getMethod() : "+invocation.getProxy().getMethod()); System.out.println("invocation.getProxy().getNamespace( : "+invocation.getProxy().getNamespace()); System.out.println("invocation.getResult() : "+invocation.getResult());
拦截器的处理操作一般被人称为执行前操作和执行后操作。
我的理解:
action等的执行可以比喻成去一个地方拿一件东西回来,有去必须有会,路上可以有各个拦截器,在action内容执行之前的拦截器的操作被称为拦截前操作,在action内容执行之后的操作被称为拦截后操作。拦截器的执行有点想多个回子。
判断拦截前后操作看操作相对于invocation.invoke的顺序。
拦截器的配置:
这里首先说明一点:struts2的框架的功能基本上是由拦截器实现的,核心过滤器起到承接的作用。所以struts2默认就使用的拦截器我们一般情况下是不能缺少的。在struts-default.xml中可以发现,默认使用了defaultStack拦截器栈。我们自定义的package一般都是继承自struts-default这个包,所以不需要配置拦截器。还有就是struts-default中配置的是默认拦截器栈,如果你要使用其他拦截器了,就代表你使用的不是默认的拦截器栈,那么拦截器栈就需要重新使用。
局部配置:
这个说法表示的是拦截器作用于单个action。
行为:
首先在package内定义拦截器。然后在action中引用拦截器。
例子:
<interceptors> <interceptor name="expressionInterceptor" class="cn.itcast.aop.ExpressionInterceptor"/> </interceptors>
<action name="userAction_save" class="cn.itcast.aop.UserAction" method="save"> <interceptor-ref name="defaultStack"/> <interceptor-ref name="expressionInterceptor"/> <result name="success">/aop/success.jsp</result> <result name="error">/aop/error.jsp</result> </action>
全局配置:
指的是拦截器拦截的是package内的所有action的请求
行为:
先声明自定义拦截器,再声明自定义拦截器栈,将需要的拦截器放入,然后设置自定义拦截器栈为默认拦截器栈。
例子:
<interceptors><!-- 声明自定义拦截器 --><interceptor name="expressionInterceptor" class="cn.itcast.aop.ExpressionInterceptor"/><!-- 声明自定义拦截器栈 --><interceptor-stack name="expressionInterceptorStack"> <interceptor-ref name="defaultStack"/><!-- 配置使用自定义拦截器 --><interceptor-ref name="expressionInterceptor"/> </interceptor-stack> </interceptors><!-- 配置struts2框架执行,执行的是自定义拦截器栈 --><default-interceptor-ref name="expressionInterceptorStack"/>