您的位置:首页 > 产品设计 > UI/UE

ValueStack---对OGNL的扩展

2016-04-21 18:42 645 查看
valueStack 是xwork用以对OGNL的计算进行扩展的一个特殊的数据结构。

实际上是对OGNL三要素中的Root对象进行扩展。1,ValueStack从数据结构的角度被定义为对象的集合,2.ValueStack规定自身这个集合的所有对象,在进行OGNLj计算时被视为Root对象。ValueStack的数据结构特征是栈结构。

ValueStack

Struts2是通过ValueStack来进行赋值与取值的。

ValueStack实际上就是对OGNL的封装,OGNL主要的功能就是赋值与取值。

ValueStack中的数据,分两个部分存放:root和context

同时ValueStack暴露相关的接口(赋值和取值):

void setValue(String expr, Object value);

Object findValue(String expr);

通过OGNL表达式对ValueStack中的数据进行操作。

root

ValueStack中的root对象是CompoundRoot。

CompoundRoot继承了ArraryList,提供了额外的方法:push()和pop()方法,

用来对root对象中所包含的数据进行存取。

正是通过这两个方法,CompoundRoot变成了一个栈结构.

压栈操作,将导致对象被放到CompoundRoot的第0个元素上(第0个元素是栈顶),其它对象被依次往后移动;

出栈操作,将导致CompoundRoot的第0个元素被移除(即栈顶元素被弹出),其它对象被依次往前移动

OGNL只能访问被压入堆栈(CompoundRoot)中的元素。

在Struts2中,一个请求在最终到达Action的方法之前,Action对象本身会被压入

ValueStack的CompoundRoot对象中。

所以Action对象是CompoundRoot对象中的一个元素,可以使用OGNL表达式直接访问。

在jSP页面中,使用<s:property value=”ognl表达式”/>标签,将CompoundRoot栈中的值取出。

在<s:property>标签中的OGNL表达式,最终会交给ValueStack来解释。

比如:"username"就是一个OGNL表达式,意思是调用root对象的getUsername()方法。

Context

由于在OGNL中,不支持多个root对象,但在struts2的OGNL的表达式中,

有可能需要访问到多个毫不相干的对象。这时候,我们把表达式中需要用到的对象放到Map中,

传递给OGNL,进行访问。这个Map对象,称为context。

可见valueStack对OGNL进行了扩展,使OGNL表达式可以访问到多个root对象。

要在表达式中访问到context中的对象,需要使用“#对象名称”的语法规则。

#表示将context对象的元素放入到CompoundRoot对象的栈顶。访问完后,

context对象的元素会从栈顶移出,自动释放。

当CompoundRoot栈中存在多个不相干的root对象时,使用 #root
. 进行访问,

n是root对象当前在栈中的顺序。从0开始。

在真实的环境下,这个对象图可能会极其复杂,但是通过基本的getters方法,都应该能够访问到某个对象的其它关联对象。

【对象图的导航,必须通过getters方法进行导航】

下述代码将创建一个User对象,及其相关的一系列对象:

Java代码

User user = new User();
Group g = new Group();
Organization o = new Organization();

o.setOrgId("ORGID");
g.setOrg(o);
user.setGroup(g);

如果通过JAVA代码来进行导航(依赖于getters方法),导航到Organization的orgId属性,如下所示:

//用JAVA来导航访问
user.getGroup().getOrg().getOrgId(); String value = (String)Ognl.getValue("group.org.orgId", user);

Ognl.getValue()方法的第一个参数,就是一条OGNL表达式,第二个参数是指定在表达式中需要用到的root对象!

public interface ValueStack{
//获取CompoundRoot,它包含了所有栈内元素的容器结构
public abstract CompoundRoot getRoot();
//获取栈顶元素,并不改变栈本身
public abstract Object peek();
//获取栈顶元素,并将其从栈中删除
public abstract Object pop();
//将对象压入栈,置于栈顶
public abstract void push(Object o);
//获取栈的大小
public abstract intsize();
//将传入的表达式进行求值计算
public abstract Object findValue(String s);
//将传入的表达式进行写值计算
public abstract void setValue(String s,Object o);

}
xwork中的ValueStack的实现类OgnlValueStack,CompoundRoot继承了ArrayList,ArrayList实现List接口,天生的容器,天生的链表结构。ValueStack是xwork框架进行OGNL计算的场所,也是xwork框架进行数据访问的基础。
OGNL进行表达式计算的基本逻辑:从栈的顶端开始对每个栈内的元素进行表达式匹配计算,并返回第一个成功匹配的表达式计算结果。ValueStack支持多个Root对象的OGNL操作的本质是栈内元素遍历。ValueStack内部所维护的栈结构其实是ArrayList,所以可以通过数组下标的形式对栈结构的每一个元素进行访问。

深入ValueStack的实现:CompoundRoot详解,子栈,链式递归调用

OGNL三要素:OGNL表达式、Root表达式、上下文环境。CompoundRoot是OGNL计算的Root对象,承担栈的职责的数据结构。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: