1:拦截器类似web过滤器,在action执行之前或者执行之后去取一些操作
2:拦截器栈就是递归调用
strust2的工作流程:
客户端通过HttpServletRequest向Tomcat容器发送请求—->过滤器(核心控制器StrutsPrepareAndexecuteFiler)—->
核心控制器访问ActionMapper来决定是否调用某个action(如果是jsp页面等则不会调用action)——>
核心控制权ActionProxy(action代理)—->ConfigurationManager(配置管理器)加载struts.xml找到要调用的action—>
ActionProxy(action代理)创建Action invocation实例—>调用拦截器123————》拦截器执行完后才执行action
调用action业务处理方法 同时这个方法返回一个 字符串结果—>根据字符串去匹配视图—>再次倒序执行拦截器321
—>-最后通过HttpServletRequest响应请求
自定义拦截器
方法一:实现Interceptor接口
void init():初始化拦截器所需资源
void destory():释放在init()分配的资源
String intercept(ActionInvocation ai) throws Exception
实现拦截器功能
利用ActionInvocation参数获取Action状态
返回result字符串作为逻辑视图方式二:继承AbstractInterceptor类
提供了init()和destory()方法的空实现
只需要实现intercept方法即可
示例:计算Action的执行时间
实现步骤:创建拦截器,在配置文件中定义拦截器并引用它
在执行Action之前先拦截,统计当前时间,之后统计执行Action之后的时间
Action的执行时间=执行Action之后的时间-执行Action之前的时间
定义一个拦截器:
第一步:1.创建一个继承自AbstractInterceptor/Interceptor的类;2.实现intercept方法(后者需要实现init()和destory()方法)。
第二步:1.在XML文件中对拦截器进行注册;2.在相应的Action中进行引用。
定义拦截器
定义一个类继承于AbstractInterceptor
@Override
public String intercept(ActionInvocation arg0) throws Exception {
// 1.执行action之前,统计时间
long start = System.currentTimeMillis();
// 2.执行下一个拦截器,如果是最后一个拦截器,就会执行action
String result = arg0.invoke();
// 3.执行action之后,统计时间
long end = System.currentTimeMillis();
System.out.println("花费时间为:" + (end - start) + "ms");
return result;
}
在struts.xml中注册拦截器和对应action配置拦截器
<!-- 注册拦截器 -->
<interceptors>
<interceptor name="mytimer" class="com.TimerInterceptor"></interceptor>
</interceptors>
<action name="timer" class="com.TimerAction">
<result>/success.jsp</result>
<!-- 引用拦截器 -->
<interceptor-ref name="mytimer"></interceptor-ref>
</action>
struts2内建拦截器
param拦截器:负责将请求参数设置为Action属性
staticParams拦截器:将配置文件中action元素的子元素param参数设置为Action属性
servletConfig拦截器:将源于Servlet API的各种对象注入到Action,必须实现对应接口
fileUpload拦截器:对文件上传提供支持,将文件和元数据设置到对应的Action属性
exception拦截器:捕获异常,并且将异常映射到用户自定义的错误页面
validation拦截器:调用验证框架进行数据验证
默认拦截器栈
在struts-default.xml中定义一个defaultStack拦截器栈,并将其指定为默认拦截器。
只要在定义包的过程中继承struts-defualt包,那么defaultStack将是默认的拦截器
当为包中的某个action显式指定了某个拦截器,则默认拦截器不会起作用。
拦截器栈中的各个拦截器的顺序很重要。
为Action显示引用拦截器后,默认的拦截器defaultStack不再生效,需手工引用,如果依然想使用默认的拦截器栈,最好把默认的拦截器写在自定义拦截器上面。
<default-interceptor-ref name=”defaultStack”/>
当显示的引用了自己的拦截器,则默认的拦截器栈则不会生效,需要手工配置
<action name="timer" class="com.TimerAction">
<result>/success.jsp</result>
<!-- 默认拦截器栈 -->
<interceptor-ref name="defaultStack"></interceptor-ref>
<!-- 引用拦截器 -->
<interceptor-ref name="mytimer"></interceptor-ref>
</action>