天天看點

struts2 OGNL # % $

下午對這個地方一直感覺很模糊……然後“決心”查一查,查了之後還是有效果的!嘿嘿……野豬,加油!野豬記住!你是一隻野豬,現在是,将來也是!要學會獨立!嘿嘿……說正題吧……

一、"#"的用法

   1、 通路OGNL上下文和Action上下文,#相當于ActionContext.getContext();下表有幾個ActionContext中有用的屬性:  

        parameters  包含目前HTTP請求參數的Map #parameters.id[0]作用相當于request.getParameter("id") 

       request 包含目前HttpServletRequest的屬性(attribute)的Map #request.userName相當于request.getAttribute("userName") 

       session 包含目前HttpSession的屬性(attribute)的Map #session.userName相當于session.getAttribute("userName") 

       application 包含目前應用的ServletContext的屬性(attribute)的Map #application.userName相當于application.getAttribute("userName") 

       attr 用于按request > session > application順序通路其屬性(attribute) #attr.userName相當于按順序在以上三個範圍(scope)内讀取userName屬性,直到找到為止 

     2、用于過濾和投影(projecting)集合,如books.{?#this.price<100}; 

     3、構造Map,如#{'foo1':'bar1', 'foo2':'bar2'}。

二、"%"的用法 

    “%”符号的用途是在标志的屬性為字元串類型時,計算OGNL表達式的值。例如在Ognl.jsp中加入以下代碼: 

    <h3>%的用途</h3>

    <p><s:url value="#foobar['foo1']" /></p>

    <p><s:url value="%{#foobar['foo1']}" /></p>

三、"$"的用法 

    1、用于在國際化資源檔案中,引用OGNL表達式 

    2、在Struts 2配置檔案中,引用OGNL表達式 

     例如:

         <action name="AddPhoto" class="addPhoto">

            <interceptor-ref name="fileUploadStack" />           

            <result type="redirect">ListPhotos.action?       albumId=${albumId}</result>

        </action>

struts2中的OGNL上下文

struts2對OGNL上下文的概念又做了進一步擴充,在struts2中,OGNL上下文通常如下所示:

|–request

|

|–application

context map—|–OgnlValueStack(root) [ user, action, OgnlUtil, ... ]

|–session

|–attr

|–parameters

我們可以使用”#requet”通路HttpServletRequest對象, “#session”通路HttpSession對象,但請注意”根對象”是什麼?是ValueStack!

那麼ValueStack是什麼?值棧。也就是一組對象的堆棧。也就是說,在struts2中,根對象不是我們通常的一個對象,而是一組對象。我們可以 push新的對象到值棧中,也可以彈出值棧的棧頂對象。如上圖所示,假設我們将user對象push到值棧中,那麼如下的表達式将與之前我們見過的表達式一樣,具有相同的結果:

Java代碼

name // 取使用者的姓名

age // 取使用者年齡

birthday // 取使用者生日

customer.name // 取使用者所屬客戶的名稱

#request.parameters // 取請求參數

也就是說,我們使用name這個表達式的時候,ONGL會取”根對象”的name屬性,但現在根對象是ValueStack!那麼通路 ValueStack的name屬性意味着什麼呢?這意味着: ValueStack會先檢視棧頂元素是否有name屬性,如果有就傳回該屬性值,否則取出棧頂下的元素,繼續檢視,直到棧底為止。

關于ValueStack

Struts2的Action類通過屬性可以或得所有相關的值,如請求參數、action配置參數、向其他Action傳遞屬性值(通過Chain結果)等等。

要獲得這些參數值,我們要做的唯一一件事就是在Action類中聲明與參數同名的屬性,在Struts2調用Action類的Action方法之前,就會為相應的Action屬性指派,要完成這個功能,有很大程度上,Struts2要依賴ValueStack對象。這個對象貫穿整個Action的生命周期(每個Action類的對象執行個體會擁有一個ValueStack對象)。當Struts2接收到一個.action的請求後,會先建立Action類的對象執行個體,但并不會調用Action方法,而是先将Action類的相應屬性放到ValueStack對象的頂層節點(ValueStack對象相當于一個棧)。隻是所有的屬性值都是預設的值,如String類型的屬性值為null,int類型的屬性值為0等。處理完上述工作後,Struts2就會調用攔截器鍊中的攔截器,當調用完所有的攔截器後,最後會調用Action類的Action方法,在調用Action方法之前,會将ValueStack對象頂層節點中的屬性值賦給Action類中相應的屬性,注意,在這裡就給我們呆了很大的靈活性。也就是說,在Struts2調用攔截器的過程中,可以改變ValueStack對象中屬性的值,當改變某個屬性之後,Action類的相應屬性值就會變成在攔截器中最後改變該屬性的這個值。

從上面的描述很容易知道,在Struts2的Action類可以獲得與屬性同名的參數值就是通過不同的攔截器來處理的,如獲得請求參數的攔截器是params,獲得Action的配置參數的攔截器是staticParams等,在這些攔截器内部讀取相應的值,并更新ValueStack對象頂層節點的相應屬性的值。而ValueStack對象就像一個傳送帶,将屬性的值從一個攔截器傳到了另一個攔截器(當然,在這期間,屬性值可能改變),最後會傳到Action對象,并将ValueStack對象中的屬性的值的終值賦給Action類的相應屬性。

繼續閱讀