struts2 OGNL # % $

來源:互聯網
上載者:User

一、"#"的用法
   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類的相應屬性。

1、值棧(ValueStack)
Struts2將OGNL上下文設定為Struts2中的ActionContext(內部使用的仍然是OgnlContext),並將值棧設為OGNL的根對象。
我們知道,OGNL上下文中的根對象可以直接存取,不需要使用任何特殊的“標記”,而引用上下文中的其他對象則需要使用“#”來標記。由於值棧是 上下文中的根對象,因此可以直接存取。那麼對於值棧中的對象該如何訪問呢?Struts2提供了一個特殊的OGNLPropertyAccessor,它 可以自動尋找棧內的所有對象(從棧頂到棧底),直接找到一個具有你所尋找的屬性的對象。也就是說,對於值棧中的任何對象都可以直接存取,而不需要使用 “#”。
假設值棧中有兩個對象:student和employee,兩個對象都有name屬性,student有學號屬性number,而 employee有薪水屬性salary。employee先入棧,student後入棧,位於棧頂,那麼對於運算式name,訪問的就是student 的name屬性,因為student對象位於棧頂;運算式salary,訪問的就是employee的salary屬性。正如你所見,訪問值棧中的對象屬 性或方法,無須指明對象,也不用“#”,就好像值棧中的對象都是OGNL上下文中的根對象一樣。這就是Struts2在OGNL基礎上做出的改進。
2、[N]文法
如上所述,如果想要訪問employee的name屬性,應該如何寫運算式呢?我們可以使用[N].xxx(N是從0開始的整數)這樣的文法來指定從哪一個位置開始向下尋找對象的屬性,運算式[1].name訪問的就是employee對象的name屬性。
在使用[N].xxx文法時,要注意位置序號的含義,它並不是表示“擷取棧中索引為N的對象”,而是截取從位置N開始的部分棧。
3、top關鍵字
top用於擷取棧頂的對象,結合[N].xxx文法,我們就可以擷取棧中任意位置的對象。
如:[0].top,[1].top等
4、訪問靜態成員
除了使用標準的OGNL運算式訪問靜態欄位和靜態方法外,Struts2還允許你不指定完整的類名,而是通過“vs”首碼來調用儲存在棧中的靜態欄位和靜態方法。
@vs@FOO_PROPERTY
@vs@someMethod()
@vs1@someMethod()
vs表示ValueStack,如果只有vs,那麼將使用棧頂對象的類;如果在vs後面跟上一個數字,那麼將使用棧中指定位置處的對象類。
5、值棧中的Action執行個體
Struts2架構總是把Action執行個體放在棧頂。因為Action在值棧中,而值棧又是OGNL中的根,所以引用Action的屬性可以省略“#”標記,這也是為什麼我們在結果頁面中可以直接存取Action的屬性的原因。
6、Struts2中的命名物件
Struts2還提供了一些命名物件,這些對象沒有儲存在值棧中,而是儲存在ActionContext中,因此訪問這些對象需要使用“#”標記。這些命名物件都是Map類型。
parameters
用於訪問請求參數。如:#parameters['id']或#parameters.id,相當於調用了HttpServletRequest對象的getParameter()方法。
注意,parameters本質上是一個使用HttpServletRequest對象中的請求參數構造的Map對象,一量對象被建立(在調用Action執行個體之前就已經建立好了),它和HttpServletRequest對象就沒有了任何關係。
request
用於訪問請求屬性。如:#request['user']或#request.user,相當於調用了HttpServletRequest對象的getAttribute()方法。
session
用於訪問session屬性。如:#session['user']或#session.user,相當於調用了HttpSession對象的getAttribute()方法。
application
用於訪問application屬性。如:#application['user']或#application.user,相當於調用了ServletContext的getAttribute()方法。
attr
如果PageContext可用,則訪問PageContext,否則依次搜尋request、session和application對象。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.