值栈的含义正如它的名字所表示的那样——对象所组成的栈。OGNL的全称是Object Graph NavigationalLanguage(对象图导航语言),提供了访问值栈中对象的统一方式。它是一种功能强大的表达式语言(ExpressionLanguage,简称为EL),通过它简单一致的表达式语法,可以存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化等功能。它使用相同的表达式去存取对象的属性。
值栈中的对象构成及其排列顺序如下所示:
1.
2.
3.
4.
访问值栈可以有很多方法,其中最常用的一种就是使用JSP,Velocity或者Freemarker提供的标签。还有就是使用HTML标签访问值栈中对象的属性;结合表达式使用控制标签(例如if,elseif和iterator);使用data标签(set和push)来控制值栈本身。
在使用值栈时,我们无须关心目标对象的作用域。如果要使用名为“name”的属性,直接从值栈中进行查询就可以了。值栈中的每一个元素,都会按照排列顺序依次检查是否拥有该属性。如果有的话,那么就返回对应的值,查询结束。如果没有的话,那么下一个元素就会被访问……直到到达值栈的末尾。这个功能非常强大,我们根本不需要知道所需要的值在什么地方——存在于Action,模型或是HTTP请求中——只要这个值存在,它就会被返回。
但它也有个缺点。如果所请求的是很常见的属性(例如“id”),而你想要从某个特定的对象中(例如action)获取该属性的值,这时候值栈中第一个满足条件的对象返回的属性值就可能不是所想要的结果了。返回结果的确是“id”属性的值,但它可能来自JSP标签,临时对象或者模型对象。这时候就需要用到OGNL来增强值栈的功能了。OSGL并不仅限于访问对象属性,如果我们知道某个action在值栈中的深度,那么就可以用“[2].id”来替换掉“id”。
实际上OGNL是一套完整的表达式语言。在OGNL里面,可以用“.”来遍历对象图(比如说,使用“person.address”而不是“getPerson().getAddress()”),它还提供了类型转换,方法调用,集合的操作与生成,集合间的映射,表达式运算和lambda表达式。OGNL的网站上提供了一套完整的指南,地址为
http://www.ognl.org/2.6.9/Documentation/html/LanguageGuide/index.html。