6.4 OGNL介绍
OGNL就是Object Graph Navigation Language的缩写(对象图形导航语言)。可以从http://sw.ognl.org获取OGNL的完整文档。这里只介绍与Struts2共存的一部分OGNL功能。
6.4.1 OGNL概述
Struts2使用了标准的上下文命名来进行OGNL表达式求值。OGNL有一个根对象的概念(在Struts2中,它就是ValueStack)。顺着根对象,其他对象被放置在context map中(作为上下文引用),包括session、application、request、attr这些map。这些对象与根对象无关,它们只是存在于context map的一边(保存在context map中)。所以,访问这些对象时需要使用 # 来告诉OGNL不要在根对象中寻找,而是在其他的上下文中进行寻找,如图6.12所示。
注意 context map中还有其他的对象,在这个例子中只引用了一部分。
在一个Struts2程序流程中,action中的实例已经被保存在ValueStack中,不用写 # 就可以引用这些bean属性了。
<s: property value="myBean.myProperty"/>
对于sessions、request,或者context map中的其他对象需要使用#来引用。例如:
<s:property value="#session.mySessionPropKey"/> <s:property value="#session['mySessionPropKey']"/> <s:property value="#attr.mySessionPropKey"/>
6.4.2 OGNL中的集合
在Struts2中经常要处理集合类(map、list和set),在select标签中经常会用到它们。
(1)list
list的语法:{e1,e2,e3}。下面的代码会创建一个包含String"name1","name2" and "name3"的List。它还选择了"name2"作为默认值。
<s:select label="label" name="name" list="{'name1','name2','name3'}" value="%{'name2'}" />
(2)map
map的语法:#{key1:value1,key2:value2}。下面的代码会创建一个map,它将string "foo"映射到string"foovalue",将string"bar"映射到string"barvalue":
<s:select label="label" name="name" list="#{'foo':'foovalue', 'bar':'barvalue'}" />
(3)查找
可以通过in和not in操作来确定一个元素是否存在于一个集合中,如实例6-16所示。
【实例6-16】OGNL在list中查找:ognl_test.jsp
01 <%@ taglib prefix="s" uri="/struts-tags"%> 02 <html> 03 <s:if test="'foo' in {'foo', 'bar'}"> <!--关于选择标签--> 04 muhahaha 05 </s:if> 06 <s:else> 07 boo 08 </s:else> 09 <!--OGNL语言, 直接可以在标签属性中使用--> 10 <s:if test="'foo' not in {'foo', 'bar'}"> 11 muhahaha 12 </s:if> 13 <s:else> 14 boo 15 </s:else> 16 </html>
图6.13 浏览页面
【运行程序】浏览该页面,结果如图6.13所示。
【代码剖析】在上述代码中,通过OGNL实现了集合list中的查找。
(4)过滤
过滤一个集合产生的子集叫做投影,可以在collection中使用通配符来获得这些投影。
❑ ?—所有符合选择逻辑的元素。
❑ ^—符合选择逻辑的第一个元素。
❑ $—符合选择逻辑的最后一个元素。
选择一个person(人)对象的所有male relatives(男性亲属)的子集代码应该如这样:
person.relatives.{? #this.gender == 'male'}