什么是ActionContext?
ActionContext是map结构的容器,ActionContext是Action的上下文,存放Action执行过程中数据信息。ActionContext存放Action的数据,request,session,application数据等。每次请求都会为当前线程创建一个新的ActionContext。而ActionContext采用了ThreadLocal的方式来存放ActionContext,所以ActionContext线程安全。ThreadLocal变量为每个线程提供独立的变量值的副本,使每个线程可以独立地使用自己的副本,而不会和其他线程发生冲突。
(Struts1的action必须依赖于web容器,他的execute方法会自动获得HttpServletRequest和HttpServletResponse对象,从而可以与web容器进行交互,Struts2的action不用依赖于web容器,本身就是一个普通的java类,需要request对象的说话,通过ActionContext来处理)
通过ActionContext获取的request等值不是真正的HttpServletRequest对象,而是将这对象的值重新封装成map对象,这样的封装,我们既获取了我们需要的值,同时避免了跟web容器直接打交道,实现了完全的解耦。
获取ActionContext
ActionContext.getContext()获取。由于ActionContext是线程安全的,并且是静态方法获取的,所以在本线程的非Action类中也可以直接访问。注意:ActionContext是基于请求创建的,所以在非请求的线程中是不能使用的。
ActionContext的简图(starUML画时序图)
ThreadLocal模式
public class Test {
public static void main(String[] args) {
//存放线程局部变量的容器,线程局部变量(ThreadLocal)其实的功用非常简单,就是为每一个使用该变量的线程都提供一个变量值的副本
final ThreadLocal<String> ac = new ThreadLocal<String>();
ac.set("siggy");
new Thread(new Runnable() {
@Override
public void run() {
//内部类引用外部类的局部变量,该变量一定要是final
System.out.println("thread=" + ac.get());
}
}).start();
System.out.println( ac.get());
}
}
执行结果
siggy
thread=null
ActionContext包含六大对象
- application
- session
- request
- parameters
- attr(依次在page→request→session→application寻找属性,找到即停止)
- ValueStack(值栈)