欢迎转载,转载请注明出处:http://it.zhutibo.com/action/article1237.htm
OGNL是Object-Graph Navigation Language的缩写,我喜欢把它翻译为:文本化对象导航语言(Graph有文本表达的含义,至少这里肯定不是指的是图形了)。
原生OGNL
原生OGNL的数据来源自stack,文章之后把它称为ognl-stack,原生ognl默认仅访问ognl-stack栈顶的对象,访问其它对象需要加上前缀。
Struts对OGNL的扩展
XWork在ognl-stack的基础上加了一个扩展:valueStack。相对于ognl-stack,valueStack仅是ognl-stack里的一个特殊对象。
XWork把ognl对ognl-stack的默认栈顶访问做了一些修改,使ognl默认访问ognl-stack里的valueStack(而valueStack一般不是ognl-stack的栈顶元素)。所以在XWork框架下面(Struts继承自XWork框架),如果要访问valueStack的其它元素的话,需要加上‘#’前缀。
注意struts2标签的一些不明确的api
这一点必须说明,struts2一些标签库的api好多地方写得不明确,经常说的是"push the value to the value stack",其实,这里指的value stack其实一般是ognl-stack:比如
<s:set var="obj" value=""/>这里面key其实是放在ognl-stack里的,所以访问时要加前缀:#obj.something。
<s:push value="obj"/> push标签是真正把obj代表的对象放到valueStack栈顶的。所以,之后可以直接访问obj里的字段,甚至不用任何前缀。如果你要获得sth对象本身,可以用这个表达式:[0].top。整个“[0].top”表达式没有ognl-stack前缀修饰"#",所以像之前所说的,它默认访问valueStack。其中“[0]”表示从valueStack的第0个元素开始截取栈,top表示获得截取后的栈顶元素。
valueStack
valueStack非常值得一说,与一般容器对象不同,valueStack有一个特性:能把元素对象的get方法直接做为valueStack自身的接口暴露出来,并且相同get方法栈顶优先。
最后总结一下:struts里,真正把对象压入到valueStack的情况其它很少,我现在能想起来的有两个地方。一个是s:push标签,一个是实现ModelDriven接口对象里的model;其它一般带var属性的标签其实一般都是把变量放到ognl-stack栈顶,但由于XWork的扩展,所以访问时你仍然需要加上前缀'#'。
一些使用
- 访问ognl-stack里对象
#obj.something - 访问valueStack栈顶对象属性
something - 访问valueStack栈顶对象
[0].top - 访问valueStack栈顶开始第二个对象
[1].something - 访问静态字段
@full.package.name.Obj@SOMETHING - 访问杖举(杖举在Java运行时其实也是普通类,一般访问方式跟静态字段一样)
有关杖举原理可查看我的另一篇文章:Java “枚举类型”详解
struts相关文章:感受一下struts2框架设计及扩展考虑