一、什么是OGNL,有什么特點(diǎn)?
OGNL(Object-Graph Navigation Language),大概可以理解為:對(duì)象圖形化導(dǎo)航語(yǔ)言。是一種可以方便地操作對(duì)象屬性的開(kāi)源表達(dá)式語(yǔ)言。OGNL有如下特點(diǎn):
1、支持對(duì)象方法調(diào)用,形式如:objName.methodName();
2、支持類(lèi)靜態(tài)的方法調(diào)用和值訪問(wèn),表達(dá)式的格式為@[類(lèi)全名(包括包路)]@[方法名 | 值名],例如:
@java.lang.String@format('foo %s', 'bar')或@tutorial.MyConstant@APP_NAME;
3、支持賦值操作和表達(dá)式串聯(lián),例如:
price=100, discount=0.8, calculatePrice(),這個(gè)表達(dá)式會(huì)返回80;
4、訪問(wèn)OGNL上下文(OGNL context)和ActionContext;
5、操作集合對(duì)象。
二、使用OGNL表達(dá)式
OGNL要結(jié)合struts標(biāo)簽來(lái)使用。由于比較靈活,也容易把人給弄暈,尤其是“%”、“#”、“$”這三個(gè)符號(hào)的使用。由于$廣泛應(yīng)用于EL中,這里重點(diǎn)寫(xiě)%和#符號(hào)的用法。
1、“#”符號(hào)有三種用途:
(1)、訪問(wèn)非根對(duì)象(struts中值棧為根對(duì)象)如OGNL上下文和Action上下文,#相當(dāng)于ActionContext.getContext();下表有幾個(gè)ActionContext中有用的屬性:
parameters
包含當(dāng)前HTTP請(qǐng)求參數(shù)的Map
#parameters.id[0]作用相當(dāng)于request.getParameter("id")
request
包含當(dāng)前HttpServletRequest的屬性(attribute)的Map
#request.userName相當(dāng)于request.getAttribute("userName")
session
包含當(dāng)前HttpSession的屬性(attribute)的Map
#session.userName相當(dāng)于session.getAttribute("userName")
application
包含當(dāng)前應(yīng)用的ServletContext的屬性(attribute)的Map
#application.userName相當(dāng)于application.getAttribute("userName")
注:attr 用于按request > session > application順序訪問(wèn)其屬性(attribute),#attr.userName相當(dāng)于按順序在以上三個(gè)范圍(scope)內(nèi)讀取 userName屬性,直到找到為止。用于過(guò)濾和投影(projecting)集合,如books.{?#this.price<100};構(gòu)造 Map,如#{'foo1':'bar1', 'foo2':'bar2'}。
(2)、用于過(guò)濾和投影(projecting)集合,如: books.{?#this.price>35}
books.{?#this.price>35}
(3)、構(gòu)造Map,如: #{'foo1':'bar1', 'foo2':'bar2'}
#{'foo1':'bar1', 'foo2':'bar2'}這種方式常用在給radio或select、checkbox等標(biāo)簽賦值上。如果要在頁(yè)面中取一個(gè)map的值可以這樣寫(xiě):
<s:property value="#myMap['foo1']"/>
<s:property value="#myMap['foo1']"/>
2、“%”符號(hào)的用途是在標(biāo)簽的屬性值被理解為字符串類(lèi)型時(shí),告訴執(zhí)行環(huán)境%{}里的是OGNL表達(dá)式。很有點(diǎn)類(lèi)似javascript里面的eval_r()功能,例如:
var oDiv = eval_r("document.all.div"+index)
var oDiv = eval_r("document.all.div"+index)
當(dāng)index變量為1時(shí),語(yǔ)句就會(huì)被當(dāng)作var oDiv = document.all.div1
var oDiv = document.all.div1來(lái)執(zhí)行。%{}就是起這個(gè)作用。舉例:
<s:set name="myMap" value="#{'key1':'value1','key2':'value2'}"/> 第1行
<s:property value="#myMap['key1']"/> 第2行
<s:url value="#myMap['key1']" /> 第3行
<s:set name="myMap" value="#{'key1':'value1','key2':'value2'}"/> 第4行
<s:property value="#myMap['key1']"/> 第5行
<s:url value="#myMap['key1']"/> 第6行
上面的代碼第2行會(huì)在頁(yè)面上輸出“value1”,而第3行則會(huì)輸出"#myMap['key1']"這么一個(gè)字符串。如果將第3行改寫(xiě)成這樣:
<s:url value="%{#myMap['key1']}"/>
<s:url value="%{#myMap['key1']}"/>
則輸出為“value1”。
這說(shuō)明struts2里不同的標(biāo)簽對(duì)ognl的表達(dá)式的理解是不一樣的。如果當(dāng)有的標(biāo)簽“看不懂”類(lèi)似“#myMap['key1']”的語(yǔ)句時(shí),就要用%{}來(lái)把這括進(jìn)去,“翻譯”一下了。
3、“$”有兩種用途
(1)、在國(guó)際化資源文件中,引用OGNL表達(dá)式。
(2)、在Struts 2配置文件中,引用OGNL表達(dá)式:
<action name="saveUser" class="userAction" method="save">
<result type="redirect">listUser.action?msg=${msg}</result>
</action>
<action name="saveUser" class="userAction" method="save">
<result type="redirect">listUser.action?msg=${msg}</result>
</action>