基本概念
Intercetor, 即为拦截器。
1) 在Struts2中,把每一个功能都用一个个的拦截器实现;用户想用struts的哪个功能的时候,可以自由组装使用。
2)Struts2中,为了方法用户对拦截器的引用,提供了拦截器栈的定义,里面可以包含多个拦截器。 文件夹(文件, 文件2) 拦截器栈(拦截器,拦截器2)
3)Struts2中,如果用户没有指定执行哪些拦截器,struts2有一个默认执行的栈,defaultStack;
一旦如果用户有指定执行哪些拦截器,默认的拦截器栈就不会被执行
拦截器的设计,就是基于组件设计的应用!
拦截器配置举例
struts-default.xml文件中,定义了struts提供的所有拦截器!
//1. 定义拦截器以及拦截器栈 <interceptors> 1.1 拦截器定义 <interceptor name="" class="" /> 1.2 拦截器栈的定义 <interceptor-stack name="defaultStack"> 引用了上面拦截器(1.1) </interceptor-stack> </interceptors> 2. 默认执行的拦截器(栈) <default-interceptor-ref name="defaultStack"/> |
API
|-- Interceptor 拦截器接口
|-- AbstractInterceptor 拦截器默认实现的抽象类;一般用户只需要继承此类即可继续拦截器开发
|-- ActionInvocation拦截器的执行状态,调用下一个拦截器或Action
自定义一个拦截器案例
步骤:
1.写拦截器类 (看生命周期)
2.配置
/**
* 自定义拦截器
*
*/
public class HelloInterceptor implements Interceptor{
// 启动时候执行
public HelloInterceptor(){
System.out.println("创建了拦截器对象");
}
// 启动时候执行
@Override
public void init() {
System.out.println("执行了拦截器的初始化方法");
}
// 拦截器业务处理方法(在访问action时候执行?在execute之前执行?)
@Override
public String intercept(ActionInvocation invocation)throws Exception {
System.out.println("2.拦截器,业务处理-开始");
// 调用下一个拦截器或执行Action (相当于chain.doFilter(..)
// 获取的是: execute方法的返回值
String resultFlag = invocation.invoke();
System.out.println("4.拦截器,业务处理-结束");
return resultFlag;
}
@Override
public void destroy() {
System.out.println("销毁....");
}
}
<?xmlversion="1.0"encoding="UTF-8"?>
<!DOCTYPEstrutsPUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<packagename="hello"extends="struts-default">
<!-- 【拦截器配置】 -->
<interceptors>
<!-- 配置用户自定义的拦截器 -->
<interceptorname="helloInterceptor"class="a_interceptor.HelloInterceptor"></interceptor>
<!-- 自定义一个栈:要引用默认栈、自定义的拦截器 -->
<interceptor-stackname="helloStack">
<!-- 引用默认栈 (一定要放到第一行)-->
<interceptor-refname="defaultStack"></interceptor-ref>
<!-- 引用自定义拦截器 -->
<interceptor-refname="helloInterceptor"></interceptor-ref>
</interceptor-stack>
</interceptors>
<!-- 【执行拦截器】 -->
<default-interceptor-refname="helloStack"></default-interceptor-ref>
<!-- Action配置 -->
<actionname="hello"class="a_interceptor.HelloAction">
<resultname="success"></result>
</action>
</package>
</struts>
常用方法与接口说明
方法名称 | 参数 | 说明 |
init | 无 | 当struts2容器实例化拦截器类的时候会调用拦截器的init方法,用于对拦截器类进行些初始化的工作,进行一些资源的初始化。 |
destroy | 无 | 当struts2容器关闭并销毁拦截器时会调用该方法,进行资源释放。 |
intercept | ActionInvocation | Intercept是拦截器的主要拦截方法,如果需要调用后续的Action或者拦截器,只需要在该方法中调用invocation.invoke()方法即可,在该方法调用的前后可以插入Action调用前后拦截器需要做的方法。如果不需要调用后续的方法,则返回一个String类型的对象即可,例如Action.SUCCESS。 |
方法名称
| 参数 | 说明 |
invoke | 无 | 调用该方法表示执行下一个拦截器,如果需要让流程继续,并将请求传送到action必须调用该方法。 |
getAction | 无 | 得到当前请求的action实例,可用于修改action的属性值,比方说可以对action的复杂数据类型进行组装 |
getInvocationContext | 无 | 返回ActionContext实例,可以通过该实例获取到当前请求的请求参数等。 |
ActionInvocation接口
该接口我们称之为Action调度者, 我在这里需要指出的是一个很重要的方法invocation.invoke()。这是ActionInvocation中的方法,这个方法具备以下2层含义
1. 如果拦截器堆栈中还有其他的Interceptor,那么invocation.invoke()将调用堆栈中下一个Interceptor的执行。
2. .如果拦截器堆栈中只有Action了,那么invocation.invoke()将调用Action执行。params
l 整个拦截器的核心部分是invocation.invoke()这个函数的调用位置。事实上,我们也正是根据这句代码的调用位置,来进行拦截类型的区分的。
在Struts2中,Interceptor的拦截类型,分成以下两类:
//代码。。
System.out.println(“before”);
invock. invoke();
System.out.println(“after”);
拦截器执行流程
时序图
启动:
创建所有拦截器、执行init()
访问:
先创建Action,
再执行拦截器,
最后:拦截器放行,执行execute();