JavaWeb从入门到精通(视频实战版)
上QQ阅读APP看书,第一时间看更新

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'}