struts2 ognl分析(轉(zhuǎn)帖)
Posted on 2008-12-02 12:58 cyantide 閱讀(1026) 評(píng)論(0) 編輯 收藏 所屬分類: struts2Struts2在OGNL基礎(chǔ)上的增強(qiáng)
1、值棧(ValueStack)
Struts2將OGNL上下文設(shè)置為Struts2中的ActionContext(內(nèi)部使用的仍然是OgnlContext),并將值棧設(shè)為OGNL的根對(duì)象。
我們知道,OGNL上下文中的根對(duì)象可以直接訪問(wèn),不需要使用任何特殊的“標(biāo)記”,而引用上下文中的其他對(duì)象則需要使用“#”來(lái)標(biāo)記。由于值棧是上下文中的根對(duì)象,因此可以直接訪問(wèn)。那么對(duì)于值棧中的對(duì)象該如何訪問(wèn)呢?Struts2提供了一個(gè)特殊的OGNLPropertyAccessor,它可以自動(dòng)查找棧內(nèi)的所有對(duì)象(從棧頂?shù)綏5?,直接找到一個(gè)具有你所查找的屬性的對(duì)象。也就是說(shuō),對(duì)于值棧中的任何對(duì)象都可以直接訪問(wèn),而不需要使用“#”。
假設(shè)值棧中有兩個(gè)對(duì)象:student和employee,兩個(gè)對(duì)象都有name屬性,student有學(xué)號(hào)屬性number,而employee有薪水屬性salary。employee先入棧,student后入棧,位于棧頂,那么對(duì)于表達(dá)式name,訪問(wèn)的就是student的name屬性,因?yàn)閟tudent對(duì)象位于棧頂;表達(dá)式salary,訪問(wèn)的就是employee的salary屬性。正如你所見(jiàn),訪問(wèn)值棧中的對(duì)象屬性或方法,無(wú)須指明對(duì)象,也不用“#”,就好像值棧中的對(duì)象都是OGNL上下文中的根對(duì)象一樣。這就是Struts2在OGNL基礎(chǔ)上做出的改進(jìn)。
2、[N]語(yǔ)法
如上所述,如果想要訪問(wèn)employee的name屬性,應(yīng)該如何寫表達(dá)式呢?我們可以使用[N].xxx(N是從0開始的整數(shù))這樣的語(yǔ)法來(lái)指定從哪一個(gè)位置開始向下查找對(duì)象的屬性,表達(dá)式[1].name訪問(wèn)的就是employee對(duì)象的name屬性。
在使用[N].xxx語(yǔ)法時(shí),要注意位置序號(hào)的含義,它并不是表示“獲取棧中索引為N的對(duì)象”,而是截取從位置N開始的部分棧。
3、top關(guān)鍵字
top用于獲取棧頂?shù)膶?duì)象,結(jié)合[N].xxx語(yǔ)法,我們就可以獲取棧中任意位置的對(duì)象。
如:[0].top,[1].top等
4、訪問(wèn)靜態(tài)成員
除了使用標(biāo)準(zhǔn)的OGNL表達(dá)式訪問(wèn)靜態(tài)字段和靜態(tài)方法外,Struts2還允許你不指定完整的類名,而是通過(guò)“vs”前綴來(lái)調(diào)用保存在棧中的靜態(tài)字段和靜態(tài)方法。
@vs@FOO_PROPERTY
@vs@someMethod()
@vs1@someMethod()
vs表示ValueStack,如果只有vs,那么將使用棧頂對(duì)象的類;如果在vs后面跟上一個(gè)數(shù)字,那么將使用棧中指定位置處的對(duì)象類。
5、值棧中的Action實(shí)例
Struts2框架總是把Action實(shí)例放在棧頂。因?yàn)锳ction在值棧中,而值棧又是OGNL中的根,所以引用Action的屬性可以省略“#”標(biāo)記,這也是為什么我們?cè)诮Y(jié)果頁(yè)面中可以直接訪問(wèn)Action的屬性的原因。
6、Struts2中的命名對(duì)象
Struts2還提供了一些命名對(duì)象,這些對(duì)象沒(méi)有保存在值棧中,而是保存在ActionContext中,因此訪問(wèn)這些對(duì)象需要使用“#”標(biāo)記。這些命名對(duì)象都是Map類型。
parameters
用于訪問(wèn)請(qǐng)求參數(shù)。如:#parameters['id']或#parameters.id,相當(dāng)于調(diào)用了HttpServletRequest對(duì)象的getParameter()方法。
注意,parameters本質(zhì)上是一個(gè)使用HttpServletRequest對(duì)象中的請(qǐng)求參數(shù)構(gòu)造的Map對(duì)象,一量對(duì)象被創(chuàng)建(在調(diào)用Action實(shí)例之前就已經(jīng)創(chuàng)建好了),它和HttpServletRequest對(duì)象就沒(méi)有了任何關(guān)系。
request
用于訪問(wèn)請(qǐng)求屬性。如:#request['user']或#request.user,相當(dāng)于調(diào)用了HttpServletRequest對(duì)象的getAttribute()方法。
session
用于訪問(wèn)session屬性。如:#session['user']或#session.user,相當(dāng)于調(diào)用了HttpSession對(duì)象的getAttribute()方法。
application
用于訪問(wèn)application屬性。如:#application['user']或#application.user,相當(dāng)于調(diào)用了ServletContext的getAttribute()方法。
attr
如果PageContext可用,則訪問(wèn)PageContext,否則依次搜索request、session和application對(duì)象。
1、值棧(ValueStack)
Struts2將OGNL上下文設(shè)置為Struts2中的ActionContext(內(nèi)部使用的仍然是OgnlContext),并將值棧設(shè)為OGNL的根對(duì)象。
我們知道,OGNL上下文中的根對(duì)象可以直接訪問(wèn),不需要使用任何特殊的“標(biāo)記”,而引用上下文中的其他對(duì)象則需要使用“#”來(lái)標(biāo)記。由于值棧是上下文中的根對(duì)象,因此可以直接訪問(wèn)。那么對(duì)于值棧中的對(duì)象該如何訪問(wèn)呢?Struts2提供了一個(gè)特殊的OGNLPropertyAccessor,它可以自動(dòng)查找棧內(nèi)的所有對(duì)象(從棧頂?shù)綏5?,直接找到一個(gè)具有你所查找的屬性的對(duì)象。也就是說(shuō),對(duì)于值棧中的任何對(duì)象都可以直接訪問(wèn),而不需要使用“#”。
假設(shè)值棧中有兩個(gè)對(duì)象:student和employee,兩個(gè)對(duì)象都有name屬性,student有學(xué)號(hào)屬性number,而employee有薪水屬性salary。employee先入棧,student后入棧,位于棧頂,那么對(duì)于表達(dá)式name,訪問(wèn)的就是student的name屬性,因?yàn)閟tudent對(duì)象位于棧頂;表達(dá)式salary,訪問(wèn)的就是employee的salary屬性。正如你所見(jiàn),訪問(wèn)值棧中的對(duì)象屬性或方法,無(wú)須指明對(duì)象,也不用“#”,就好像值棧中的對(duì)象都是OGNL上下文中的根對(duì)象一樣。這就是Struts2在OGNL基礎(chǔ)上做出的改進(jìn)。
2、[N]語(yǔ)法
如上所述,如果想要訪問(wèn)employee的name屬性,應(yīng)該如何寫表達(dá)式呢?我們可以使用[N].xxx(N是從0開始的整數(shù))這樣的語(yǔ)法來(lái)指定從哪一個(gè)位置開始向下查找對(duì)象的屬性,表達(dá)式[1].name訪問(wèn)的就是employee對(duì)象的name屬性。
在使用[N].xxx語(yǔ)法時(shí),要注意位置序號(hào)的含義,它并不是表示“獲取棧中索引為N的對(duì)象”,而是截取從位置N開始的部分棧。
3、top關(guān)鍵字
top用于獲取棧頂?shù)膶?duì)象,結(jié)合[N].xxx語(yǔ)法,我們就可以獲取棧中任意位置的對(duì)象。
如:[0].top,[1].top等
4、訪問(wèn)靜態(tài)成員
除了使用標(biāo)準(zhǔn)的OGNL表達(dá)式訪問(wèn)靜態(tài)字段和靜態(tài)方法外,Struts2還允許你不指定完整的類名,而是通過(guò)“vs”前綴來(lái)調(diào)用保存在棧中的靜態(tài)字段和靜態(tài)方法。
@vs@FOO_PROPERTY
@vs@someMethod()
@vs1@someMethod()
vs表示ValueStack,如果只有vs,那么將使用棧頂對(duì)象的類;如果在vs后面跟上一個(gè)數(shù)字,那么將使用棧中指定位置處的對(duì)象類。
5、值棧中的Action實(shí)例
Struts2框架總是把Action實(shí)例放在棧頂。因?yàn)锳ction在值棧中,而值棧又是OGNL中的根,所以引用Action的屬性可以省略“#”標(biāo)記,這也是為什么我們?cè)诮Y(jié)果頁(yè)面中可以直接訪問(wèn)Action的屬性的原因。
6、Struts2中的命名對(duì)象
Struts2還提供了一些命名對(duì)象,這些對(duì)象沒(méi)有保存在值棧中,而是保存在ActionContext中,因此訪問(wèn)這些對(duì)象需要使用“#”標(biāo)記。這些命名對(duì)象都是Map類型。
parameters
用于訪問(wèn)請(qǐng)求參數(shù)。如:#parameters['id']或#parameters.id,相當(dāng)于調(diào)用了HttpServletRequest對(duì)象的getParameter()方法。
注意,parameters本質(zhì)上是一個(gè)使用HttpServletRequest對(duì)象中的請(qǐng)求參數(shù)構(gòu)造的Map對(duì)象,一量對(duì)象被創(chuàng)建(在調(diào)用Action實(shí)例之前就已經(jīng)創(chuàng)建好了),它和HttpServletRequest對(duì)象就沒(méi)有了任何關(guān)系。
request
用于訪問(wèn)請(qǐng)求屬性。如:#request['user']或#request.user,相當(dāng)于調(diào)用了HttpServletRequest對(duì)象的getAttribute()方法。
session
用于訪問(wèn)session屬性。如:#session['user']或#session.user,相當(dāng)于調(diào)用了HttpSession對(duì)象的getAttribute()方法。
application
用于訪問(wèn)application屬性。如:#application['user']或#application.user,相當(dāng)于調(diào)用了ServletContext的getAttribute()方法。
attr
如果PageContext可用,則訪問(wèn)PageContext,否則依次搜索request、session和application對(duì)象。