一、值栈(ValueStack)是什么?
值栈(ValueStack),是Struts2的数据中转站,其中自动保存了当前Action对象和其他相关对象(包括常用的web对象的引用,如request),也可以手动保存自己是数据对象,同时也可以随时随地将对象从值栈取出或操作(通过OGNL表达式)
值栈,实际是一个接口对象的称呼,接口是Value类,实现类是OgnlValueStack类。struts2框架将ValueStack对象保存在名为"struts.valueStack"的请求(request)属性中,即值栈是request中的一个对象,一个请求对应一个Action实例和一个值栈对象。
二、值栈的数据存储结构的分析
在值栈的内部有两个逻辑部分:
ObjectStack(对象栈):保存了Action的相关对象和动作,数据存储结构是List.
ContextMap(上下文栈):保存了各种映射关系,数据存储结构是Map.
值栈对象的获取,两种方式获取的对象是同一对象:
1)request.getAttribute("struts.valueStack");
2)ActionContext.getContext().getValueStack();
[值栈小结]:
值栈是在请求对象引用了一块存储空间。
值栈包括两部分:对象栈(CompoundRoot,继承list接口)和OGNL上下文栈(OgnlContext,实现Map接口)
三、值栈的获取数据的机制
ognlValueStack类包含两个重要的属性,一个root(CompoundRoot)和一个context(OgnlContext).
在这个OgnlContext对象中,有一个默认的顶层对象root(引用),俗称root栈,下面一个对象称之为Map栈.
OGNL表达式的操作都基于OgnlContext对象,访问的规则如下:
1) 如果访问 root栈内容(CompoundRoot 对象栈内容), 不需要#,直接通过元素的名称来访问。
2) 如果访问 Map栈内容 (如request、response、session、servletContext、attr、parameters), 需要#key来引用访问,例如 #request.name 相当于 request.getAttribute("name" )
四、值栈的存取小结
值栈的主要作用就是数据的保存和获取(可以在任何地方获取)。
使用值栈的时候要思考:用什么代码存进去,然后再用什么代码取出来。
1. 如何向值栈保存数据
1) ValueStack.push(obj) :保存数据到Root栈顶-压栈顶(对象本身)-匿名
2) ActionContext.getContext().put(key,value) :保存数据到Map栈中
3) ValueStack.set(key,value):将数据保存到Root栈顶(数据对象自动被封装为Map来保存,栈顶是个map,map里面有个属性是对象)--有名字
提供Action成员变量,提供getter方法(Action就在root栈中,Action属性可以被搜索)
2.ognl表达式如何获取值栈的数据
- JSP页面获取
1) <s :property value= “name”/> 先搜索root栈对象属性(getter方法:getXxx-->xxx),再搜索map的key
2) <s:property value=”#name” /> 搜索map的key
3) 通过 [index].top 指定访问root栈某个对象 ,例如 [0].top 栈顶对象
- Action代码获取
ValueStack.findValue(ognl表达式) ; 获取值栈数据