strut2ognl
然而,我認(rèn)為struts2最復(fù)雜難學(xué)的是它內(nèi)置的ognl表達(dá)式.這個(gè)ognl在我開始學(xué)struts2時(shí),讓我云里霧里,不知如何應(yīng)對(duì).經(jīng)過幾輪 的翻看書籍,與網(wǎng)上資料查詢,還算是讓我有所明白一點(diǎn).在此記錄,以便日后溫習(xí),同時(shí),如果這篇文章對(duì)各位有哪怕一點(diǎn)幫助,那便是我最大的榮幸.
首先,要知道ognl最主要的功能就是取數(shù)據(jù),它可以利用一段簡(jiǎn)短的表達(dá)式取出各種各樣豐富的數(shù)據(jù).其次,它還附帶了一些便捷的功能,如:方法調(diào)用、 靜態(tài)方法和屬性調(diào)用、數(shù)值運(yùn)算……我們最關(guān)心的是如何取數(shù)據(jù),因此,接下來我將重點(diǎn)介紹如何取數(shù)據(jù),至于附帶功能將不做介紹。
知道了ognl最主要的功能是取數(shù)據(jù)后,那么數(shù)據(jù)從哪里取呢!ognl會(huì)從兩個(gè)地方取:一個(gè)是Action的實(shí)例屬性;另一個(gè)是 ValueStack(中文名叫值棧)。ognl會(huì)先從前者里面取,如果沒取到再到ValueStack里取。Action的實(shí)例屬性好理解,但這個(gè) ValueStack從字面上看,著實(shí)不好理解,以致于我將struts2的源碼引進(jìn)eclipse里,單步調(diào)試才算有所啟發(fā)。可以將 ValueStack初步理解為一個(gè)map,在這個(gè)map里存儲(chǔ)了request、session、application、response、 action實(shí)例、parameters數(shù)組……還有很多你不知道的對(duì)象。有了這個(gè)map,還愁數(shù)據(jù)取不到嗎。
注意:將ValueStack初步理解為一個(gè)map,只適于初學(xué)struts2的人,其實(shí)它內(nèi)部并沒這么簡(jiǎn)單。由于水平、時(shí)間有限,我并不能掌握其內(nèi) 部精髓,加上表達(dá)能力不佳,怕表達(dá)不對(duì)誤導(dǎo)大家,所以我們姑且理解ValueStack為一個(gè)map吧。如果想更深的了解的ValueStack,請(qǐng)查看 struts2的源碼。
接下來,便是取數(shù)據(jù)。取action實(shí)例的屬性數(shù)據(jù)與取ValueStack中的數(shù)據(jù)不一樣,先說取action實(shí)例的屬性數(shù)據(jù)吧。
action實(shí)例的屬性數(shù)據(jù)可以直接在struts2的標(biāo)簽中通過屬性名取到。如:<s:property value="name"/>、<s:property value="user.password"/>
注意:不要加#號(hào)。
再是取ValueStack中的數(shù)據(jù)。
struts2提供三種方式通過ognl表達(dá)式來取ValueStack中的數(shù)據(jù):#、%{}、${}
#和%{}需要放到struts2提供的標(biāo)簽里才生效。如:<s:property value="#name"/>、<s:property value="%{'hello struts2'}"/>
一、最常用的方式是:#
1.#能取request、session、application里的attribute,但需要加前綴。如:<s:property value="#session.name2"/>、<s:property value="#application.name3"/>。如果是取request范圍的attribute,那么不需要加request前綴, 加上反而取不到數(shù)據(jù),ognl默認(rèn)從request里取,如果沒有取到并不會(huì)到session或application里取。 如:<s:property value="#name"/>
2.#能取request里的請(qǐng)求參數(shù),但必須加parameters前綴,且取到的是一個(gè)數(shù)組,所以如果你要得到參數(shù)的第一項(xiàng)值,那么還要加下標(biāo)。 如:<s:property value="#parameters.name[0]"/>。這相當(dāng)于調(diào)用 request.getParameterValues("name")[0];
3.#加attr前綴能按request > session > application順序獲取attribute,這樣當(dāng)在request中取不到時(shí),會(huì)自動(dòng)向session里取,如果session里也取不到,會(huì) 再向application里取。如果取到則返回,不再向上游歷。如:<s:property value="#attr.name"/>
4.#能構(gòu)造Map,如:<s:set name="foobar" value="#{'foo1':'bar1', 'foo2':'bar2'}" /><s:property value="#foobar['foo1']" />
5.#能用于過濾和投影(projecting)集合,如:books.{?#this.price<100}
以上第4、5項(xiàng)功能,我沒有做過多介紹,因?yàn)槟壳盀橹惯@兩項(xiàng)功能我使用并不多。
二、%{}的用途是在標(biāo)簽的屬性為字符串類型時(shí),計(jì)算OGNL表達(dá)式的值。這個(gè)功能目前還沒有深刻體會(huì),故不介紹。
三、${}有兩個(gè)主要的用途。
1.用于在國際化資源文件中,引用OGNL表達(dá)式。
2.在Struts 2配置文件中,引用OGNL表達(dá)式。如 :
<action name="AddPhoto" class="addPhoto">
<interceptor-ref name="fileUploadStack" />
<result type="redirect">ListPhotos.action?albumId=${albumId}</result>
</action>
以上,其實(shí)主要介紹了#的使用,大部分情況下我們只與它打交道,另外兩種方式需要在以后的項(xiàng)目中多多使用才能有所體會(huì)。
其實(shí),我是jstl+el的忠實(shí)粉絲,在任何項(xiàng)目中,只要能用上jstl標(biāo)簽的,我決不用其它標(biāo)簽。因?yàn)樗枪俜綐?biāo)準(zhǔn),還有它簡(jiǎn)單且已熟練,我已在眾多項(xiàng)目中實(shí)戰(zhàn)演練過,有了它們,我不想在使用其它標(biāo)簽。
說到了這里,我還是有必要再多說兩句,是不是使用了struts2,就不能再用el來取數(shù)據(jù)了呢?答案是否定的,完全可以使用el來取數(shù)據(jù)。 struts2會(huì)將ValueStack里的session、application里的attribute完全復(fù)制到HttpSession、 ServletContext里,這樣el表達(dá)式照樣能取到這兩個(gè)Scope里的數(shù)據(jù)。然而,struts2并沒有將ValueStack里的 request里的attribute復(fù)制到HttpServletRequest,這是不是意味著el表達(dá)式就不能取request里的數(shù)據(jù)了呢?還是 可以,不只可以取request里的數(shù)據(jù),還可以取action實(shí)例的屬性值。神奇吧!奧秘就在struts2對(duì)request做了封裝,這個(gè)封裝類是 org.apache.struts2.dispatcher.StrutsRequestWrapper,它重寫了getAttribute()方法, 該方法先從真實(shí)的request類里取attribute,如果取到則返回,如果沒有取到則從ValueStack里取,現(xiàn)在明白了吧!
posted on 2013-01-18 13:20 楊軍威 閱讀(120) 評(píng)論(0) 編輯 收藏