struts2的ognl表達式學習心得

   經過一段時間的閉關練習,終於對struts2有所瞭解.其實struts2並不難,一看就能明白其中奧妙.我對struts2的驗證體系保留懷疑態度,因爲它的驗證消息使用標籤打在頁面上,實在太醜,在真實項目中不知道是否有人這麼做.也許是我太菜了,還不知道如何將驗證消息顯示得更友好,希望各位不吝拍磚指導.
  然而,我認爲struts2最複雜難學的是它內置的ognl表達式.這個ognl在我開始學struts2時,讓我雲裏霧裏,不知如何應對.經過幾輪的翻看書籍,與網上資料查詢,還算是讓我有所明白一點.在此記錄,以便日後溫習,同時,如果這篇文章對各位有哪怕一點幫助,那便是我最大的榮幸.
  首先,要知道ognl最主要的功能就是取數據,它可以利用一段簡短的表達式取出各種各樣豐富的數據.其次,它還附帶了一些便捷的功能,如:方法調用、靜態方法和屬性調用、數值運算……我們最關心的是如何取數據,因此,接下來我將重點介紹如何取數據,至於附帶功能將不做介紹。
  知道了ognl最主要的功能是取數據後,那麼數據從哪裏取呢!ognl會從兩個地方取:一個是Action的實例屬性;另一個是ValueStack(中文名叫值棧)。ognl會先從前者裏面取,如果沒取到再到ValueStack裏取。Action的實例屬性好理解,但這個ValueStack從字面上看,着實不好理解,以致於我將struts2的源碼引進eclipse裏,單步調試纔算有所啓發。可以將ValueStack初步理解爲一個map,在這個map裏存儲了request、session、application、response、action實例、parameters數組……還有很多你不知道的對象。有了這個map,還愁數據取不到嗎。
  注意:將ValueStack初步理解爲一個map,只適於初學struts2的人,其實它內部並沒這麼簡單。由於水平、時間有限,我並不能掌握其內部精髓,加上表達能力不佳,怕表達不對誤導大家,所以我們姑且理解ValueStack爲一個map吧。如果想更深的瞭解的ValueStack,請查看struts2的源碼。

  接下來,便是取數據。取action實例的屬性數據與取ValueStack中的數據不一樣,先說取action實例的屬性數據吧。
  action實例的屬性數據可以直接在struts2的標籤中通過屬性名取到。如:<s:property value="name"/>、<s:property value="user.password"/>
  注意:不要加#號。

  再是取ValueStack中的數據。
  struts2提供三種方式通過ognl表達式來取ValueStack中的數據:#、%{}、${}
  #和%{}需要放到struts2提供的標籤裏才生效。如:<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前綴,加上反而取不到數據,ognl默認從request裏取,如果沒有取到並不會到session或application裏取。如:<s:property value="#name"/>
  2.#能取request裏的請求參數,但必須加parameters前綴,且取到的是一個數組,所以如果你要得到參數的第一項值,那麼還要加下標。如:<s:property value="#parameters.name[0]"/>。這相當於調用request.getParameterValues("name")[0];
  3.#加attr前綴能按request > session > application順序獲取attribute,這樣當在request中取不到時,會自動向session裏取,如果session裏也取不到,會再向application裏取。如果取到則返回,不再向上游歷。如:<s:property value="#attr.name"/>
  4.#能構造Map,如:<s:set name="foobar" value="#{'foo1':'bar1', 'foo2':'bar2'}" /><s:property value="#foobar['foo1']" />
  5.#能用於過濾和投影(projecting)集合,如:books.{?#this.price<100}
  以上第4、5項功能,我沒有做過多介紹,因爲目前爲止這兩項功能我使用並不多。
  二、%{}的用途是在標籤的屬性爲字符串類型時,計算OGNL表達式的值。這個功能目前還沒有深刻體會,故不介紹。
  三、${}有兩個主要的用途。
  1.用於在國際化資源文件中,引用OGNL表達式。
  2.在Struts 2配置文件中,引用OGNL表達式。如 :
  <action name="AddPhoto" class="addPhoto">
        <interceptor-ref name="fileUploadStack" />           
        <result type="redirect">ListPhotos.action?albumId=${albumId}</result>
    </action>

  以上,其實主要介紹了#的使用,大部分情況下我們只與它打交道,另外兩種方式需要在以後的項目中多多使用纔能有所體會。
  其實,我是jstl+el的忠實粉絲,在任何項目中,只要能用上jstl標籤的,我決不用其它標籤。因爲它是官方標準,還有它簡單且已熟練,我已在衆多項目中實戰演練過,有了它們,我不想在使用其它標籤。
  說到了這裏,我還是有必要再多說兩句,是不是使用了struts2,就不能再用el來取數據了呢?答案是否定的,完全可以使用el來取數據。struts2會將ValueStack裏的session、application裏的attribute完全複製到HttpSession、ServletContext裏,這樣el表達式照樣能取到這兩個Scope裏的數據。然而,struts2並沒有將ValueStack裏的request裏的attribute複製到HttpServletRequest,這是不是意味着el表達式就不能取request裏的數據了呢?還是可以,不只可以取request裏的數據,還可以取action實例的屬性值。神奇吧!奧祕就在struts2對request做了封裝,這個封裝類是org.apache.struts2.dispatcher.StrutsRequestWrapper,它重寫了getAttribute()方法,該方法先從真實的request類裏取attribute,如果取到則返回,如果沒有取到則從ValueStack裏取,現在明白了吧!
  還有很多奧祕等着你去探索,一起加油吧!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章