基本概念
Intercetor, 即为拦截器。
1) 在Struts2中,把每一个功能都用一个个的拦截器实现;用户想用struts的哪个功能的时候,可以自由组装使用。
2)Struts2中,为了方法用户对拦截器的引用,提供了拦截器栈的定义,里面可以包含多个拦截器。 文件夹(文件, 文件2) 拦截器栈(拦截器,拦截器2)
3)Struts2中,如果用户没有指定执行哪些拦截器,struts2有一个默认执行的栈,defaultStack;
一旦如果用户有指定执行哪些拦截器,默认的拦截器栈就不会被执行
拦截器的设计,就是基于组件设计的应用!
API
|-- Interceptor 拦截器接口
|-- AbstractInterceptor 拦截器默认实现的抽象类;一般用户只需要继承此类即可继续拦截器开发
|-- ActionInvocation拦截器的执行状态,调用下一个拦截器或Action
下面我们就自定义一个拦截器来模拟其生命周期
首先写一个HelloInterceptor类,给其执行的方法打上标记
package cn.qblank.interceptor;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.I18nInterceptor;
public class HelloInterceptor extends I18nInterceptor{
public HelloInterceptor(){
System.out.println("1.创建了拦截器对象");
}
@Override
public void init() {
System.out.println("2.初始化拦截器");
}
@Override
public String intercept(ActionInvocation invocation) throws Exception {
// 调用下一个拦截器或执行Action (相当于chain.doFilter(..)
// 获取的是: execute方法的返回值
String resultFlag = invocation.invoke();
System.out.println("5.拦截器业务结束" + resultFlag);
return resultFlag;
}
@Override
public void destroy() {
System.out.println("拦截器销毁");
}
}
然后写一个HelloAction类,也给其做好标记
package cn.qblank.interceptor;
import com.opensymphony.xwork2.ActionSupport;
public class HelloAction extends ActionSupport{
public HelloAction(){
System.out.println("3.创建Action对象");
}
@Override
public String execute() throws Exception {
System.out.println("4.执行了请求处理的方法");
return SUCCESS;
}
}
再然后对其拦截器和Action进行配置hello.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="hello" extends="struts-default" namespace="/">
<!-- 拦截器配置 -->
<interceptors>
<!-- 配置用户自定义的配置 -->
<!-- class: 拦截器的完整类名 -->
<interceptor name="helloInterceptor" class="cn.qblank.interceptor.HelloInterceptor"></interceptor>
<!-- 自定义一个栈: 要引用默认栈、自定义的拦截器 用于存储各个拦截器-->
<interceptor-stack name="helloStack">
<!-- 引用默认栈 -->
<interceptor-ref name="defaultStack"></interceptor-ref>
<!-- 引用自定义拦截器 -->
<interceptor-ref name="helloInterceptor"></interceptor-ref>
</interceptor-stack>
</interceptors>
<!-- 通过调用存储拦截器的栈的方式执行拦截器 -->
<default-interceptor-ref name="helloStack"></default-interceptor-ref>
<!-- Action配置 -->
<action name="hello" class="cn.qblank.interceptor.HelloAction">
<result name="success">/index.jsp</result>
</action>
</package>
</struts>
最后配置下struts.xml,引入hello.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<!-- 总配置文件 负责引入各个子配置文件 -->
<!-- 自定义拦截器 -->
<include file="cn/qblank/interceptor/hello.xml"></include>
</struts>
然后我们开启服务器,我们再看日志中
由此我们可以看出,服务器先创建了拦截器对象,然后对拦截器进行了初始化
然后我们再向服务器发出请求
这时我们可以看到它的执行顺序
首先创建了Action对象,在进入action之前,先进入了拦截器,然后调用invocation.invoke()方法(类似于过滤器中的chain.doFilter方法)放行,看是否存在下一个拦截器,如果没有,进入Action执行请求处理的方法,在这里是execute()方法(默认执行的方法),最后进入拦截器,拦截器的业务结束,返回上一个拦截器,如果没有,直接相应浏览器的请求