转自:http://hi.baidu.com/gacmotor/blog/item/b73fc5558497b2153b293550.html
要创建一个对象的list,则用大括号括起表达式的列队。而作为方法的参数,这些表达式不能够使用逗号运算符,除非它用小括号括起。例子:
name in { null,"Untitled" }
这是测试name属性是否是null或者等于"Untitled"。
上面所述的语法会创建一个List接口实例,而没有实际上定义它的子类。
有时候,你想要创建一个Java原生的数组,例如int[]或Integer[]。OGNL创建数组的过程类似,但是即允许通过一个列表初始化,或者给定数组大小来做。
new int[] { 1, 2, 3 }
这条语句创建了一个包含三个元素的数组 1, 2和3.
要创建一个null或0个元素的数组,则使用size构造。
new int[5]
它创建了一个5个元素的数组,全部初始化为0。
Map的创建使用特殊的语法。
#{ "foo" : "foo value", "bar" : "bar value" }
创建了一个Map,并且为foo和bar初始化了值。
高级用户可能希望创建特定的Map类,在大括号之前指定。
#@java.util.LinkedHashMap@{ "foo" : "foo value", "bar" : "bar value" }
上例会创建JDK 1.4中LinkedHashMap类的实例,它能保证元素插入序是预定好的。
OGNL提供了一种简易的方式调用集合中每个元素相同的方法或者是抽出他们的值,并且存储在一个新的集合中。我们称之为从数据库中的项目投影("projection")到某张表的列的子集。例如:
listeners.{delegate}
返回一个存有所有listener的delegate的列表。参见coercion一节,可以知道OGNL如何把各种类型的对象当做集合。
在投影钟,#this变量引用当前被迭代到的元素。
objects.{ #this instanceof String ? #this : #this.toString()}
上面的语句会产生一个新的元素列表,它们是作为Objects列表的字符串值。
OGNL也提供了使用表达式从一个集合选取一些元素存入到一个新集合的方法。我们称之为从一个数据库中选择("selection")一些内容到另外一张表中记录行的自己。例如,表达式:
listeners.{? #this instanceof ActionListener}
返回一个所有元素是ActionListener类实例的元素列表。参看coercion,可以知道OGNL如何把各种类型的对象当做集合。
为了能够从列表中选取第一个匹配的元素,你可以使用下标,例如listeners.{?true }[0]。不过这个有点烦,因为匹配过程如果不返回任何结果(或者结果列表是空的)会出现ArrayIndexOutOfBoundsException异常。
选择语法允许你只选择第一匹配的元素,并且把它当成列表返回来。如果匹配不成功则返回空列表。
objects.{^ #this instanceof String }
上面会返回包含在objects中的第一是String类实例的元素。
与选择第一个元素类似,有时候你需要获得最后一个匹配的元素。
objects.{$ #this instanceof String }
上面会返回包含在objects中的最后一个是String类实例的元素
你可以像在Java中一样用new运算符创造一个新的对象。唯一的不同是,除了java.lang包中的类意外,其他的类必须指明完整类名1。(例如new java.util.ArrayList(),而不是简单的new ArrayList())。
OGNL使用与调用重载方法相同的过程选择并调用正确的构造函数。
注1:只有适当的使用默认的ClassResolver才是正确的。使用能够被映射的自定义的类解析器包,可以以更像Java中对类的引用的方式来实现。made. 参见OGNL开发者手册获取更多使用ClassResolver类的内容。
(This is only true with the default ClassResolver in place. With a custom class resolver packages can be mapped in such a way that more Java-like references to classes can be made. Refer to the OGNL Developer's Guide for details on using ClassResolver Class.)
可以使用语法@class@method(args)来调用类的静态方法。如果省略类,默认就是java.lang.Math,这样调min和max方法则更容易些。如果指定类,则必须给出完整名称。
如果你要调用一个类实例中的静态方法,你可以直接调用这个方法,就好像它是个实例方法一样。
如果方法是重载的,OGNL会使用针对重载实例方法的方式去选择正确的静态方法。
可以使用语法@class@field来引用静态成员。这个类必须是全名。
如果OGNL表达式后接括号表达式,而且括号前面没有点,OGNL会试着把第一个表达式的结果当做另外一个表达式去求值,并且会使用括号中表达式的结果当做前面那个求值的root对象。(这个地方比较拗口,说白了,就是整个表达式当函数处理了——近似的,不信看下例)第一个表达式的结果可以是任何对象。如果是个AST,OGNL会假设它是一个表达式的解析形式,并且直接翻译它。否则,OGNL会取得这个对象的String值,并且通过解析这个字符串来取得AST再去对其进行解释。例如,表达式:
#fact(30H)
查找fact变量,并且使用30的BigInteger形式作为根对象,然后把那个变量的值当做一个OGNL表达式进行解释。看看下面的例子,它使用表达式设置了一个fact变量,这个表达式返回其自身的阶乘。注意到OGNL语法中在这个双重求值运算和方法调用中会产生二义性。 OGNL通过调用任何看上去像方法调用的方式来消除二义性。例如,如果当前的对象有个fact属性,它持有OGNL阶乘表达式,你就不能使用这种方式调用它。
fact(30H)
因为OGNL会把它解释为到一个fact方法的调用。你可以通过给这个fact属性上强加括号来让OGNL按照希望的方式进行解释:
(fact)(30H)