ValueStack---对OGNL的扩展

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]. 进行访问,
n是root对象当前在栈中的顺序。从0开始。
在真实的环境下,这个对象图可能会极其复杂,但是通过基本的getters方法,都应该能够访问到某个对象的其它关联对象。
【对象图的导航,必须通过getters方法进行导航】
下述代码将创建一个User对象,及其相关的一系列对象:

Java代码
  1. User user = new User();  
  2. Group g = new Group();  
  3. Organization o = new Organization();  
  4.   
  5. o.setOrgId("ORGID");  
  6. g.setOrg(o);  
  7. user.setGroup(g);  


如果通过JAVA代码来进行导航(依赖于getters方法),导航到Organization的orgId属性,如下所示:
  1. //用JAVA来导航访问  
  2. user.getGroup().getOrg().getOrgId(); String value = (String)Ognl.getValue("group.org.orgId", user);
  3. Ognl.getValue()方法的第一个参数,就是一条OGNL表达式,第二个参数是指定在表达式中需要用到的root对象!
    public interface ValueStack{
  4. //获取CompoundRoot,它包含了所有栈内元素的容器结构
  5. public abstract CompoundRoot getRoot();
  6. //获取栈顶元素,并不改变栈本身
  7. public abstract Object peek();
  8. //获取栈顶元素,并将其从栈中删除
  9. public abstract Object pop();
  10. //将对象压入栈,置于栈顶
  11. public abstract void   push(Object  o);
  12. //获取栈的大小
  13. public abstract intsize();
  14. //将传入的表达式进行求值计算
  15. public   abstract Object findValue(String s);
  16. //将传入的表达式进行写值计算
  17. public abstract void setValue(String s,Object o);
  18. }
  19. xwork中的ValueStack的实现类OgnlValueStack,CompoundRoot继承了ArrayList,ArrayList实现List接口,天生的容器,天生的链表结构。ValueStack是xwork框架进行OGNL计算的场所,也是xwork框架进行数据访问的基础。
  20. OGNL进行表达式计算的基本逻辑:从栈的顶端开始对每个栈内的元素进行表达式匹配计算,并返回第一个成功匹配的表达式计算结果。ValueStack支持多个Root对象的OGNL操作的本质是栈内元素遍历。ValueStack内部所维护的栈结构其实是ArrayList,所以可以通过数组下标的形式对栈结构的每一个元素进行访问。

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

OGNL三要素:OGNL表达式、Root表达式、上下文环境。CompoundRoot是OGNL计算的Root对象,承担栈的职责的数据结构。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值