1、ActionContext
struts2 在每次执行Action之前都会创建新的ActionContext,ActionContext是线程安全
的,也就是说在同一个线程里ActionContext里的属性是唯一的,这样我的Action就可以在多线程
中使用。ActionContext中有个静态的ThreadLocal变量,用来存放每个Action的actionContext。
ActionContext里有6个对象,分别是valueStack、parameters、request、session、
application、attr。
ActionContext:
context map
------------
|
|--application
|
|--session
|
|--value stack(root)
|
|--request
|
|--parameters
|
|--attr (searches page, request, session, then application scopes)
|
OGNL是一个对象,属性的查询语言。在OGNL中有一个类型为Map的Context(称为上下文)
,在这个上下文中有一个根元素 (root),对根元素的属性的访问可以直接使用属性名字,但是
对于其他非根元素属性的访问必须加上特殊符号#。
一个OGNL表达式,必须选择ActionContext中的一个对象作为根对象(root),默认情况
下,是选择valueStack作为根对象,如果需要使用另外5个对象作为根对象,需要加上#前缀
如<s:property value="#session.xxx" />如果不加#前缀,则默认使用valueStack作为根
对象,这也是最常见的情况,即xxx,相当于 #valueStack.xxx。
2、ValueStack(值栈)
ValueStack中可以存储很多对象,它的一个特性是,它是一个虚拟对象,它可以将自己持
有的对象的属性,当成是自己的属性
比如说,ValueStack中有一个Action对象,而Action对象有一个name字段。那么当用OGNL
表达式取name的值的时候,不需要${action.name},而是可以直接${name}
ValueStack是一个栈的数据结构(FILO),最后进入值栈的对象,总是在ValueStack的栈
顶,这个结论很重要,因为栈顶的元素的值,会覆盖栈底的同名元素的值。
比如说,ValueStack的栈底是一个Action对象,持有一个name字段;栈顶是一个Model对
象,也持有一个name字段,那么用${name},取出来的永远是Model对象的name字段,Action对象的
name字段是不可见的