Struts2中的OGNL詳解

首先了解下OGNL的概念:

OGNL是Object Graph Navigation Language(對象圖導航語言),是一種功能強大的表達式語言,它通過簡單一致的語法,可以任意存取對象的屬性或者調用對象的方法,能夠遍歷整個對象的結構圖,實現對象屬性類型的轉換等功能。

此外,還得先需弄懂OGNL的一些知識:

1.OGNL表達式的計算是圍繞OGNL上下文進行的。
OGNL上下文實際上就是一個Map對象,由ognl.OgnlContext類表示。它裏面可以存放很多個JavaBean對象。它有一個上下文根對象。上下文中的根對象可以直接使用名來訪問或直接使用它的屬性名訪問它的屬性值。否則要加前綴“#key”。

2.Struts2的標籤庫都是使用OGNL表達式來訪問ActionContext中的對象數據的。如:<s:propertyvalue="xxx"/>。

3.Struts2將ActionContext設置爲OGNL上下文,並將值棧作爲OGNL的根對象放置到ActionContext中。

4.值棧(ValueStack) :
可以在值棧中放入、刪除、查詢對象。訪問值棧中的對象不用“#”。
Struts2總是把當前Action實例放置在棧頂。所以在OGNL中引用Action中的屬性也可以省略“#”。
 
5.調用ActionContext的put(key,value)放入的數據,需要使用#訪問。

OGNL中重要的3個符號:#、%、$:

#、%和$符號在OGNL表達式中經常出現,而這三種符號也是開發者不容易掌握和理解的部分,需要時間的積累才漸漸弄清楚……
1.#符號

#符號的用途一般有三種。

—    訪問非根對象屬性,例如#session.msg表達式,由於Struts 2中值棧被視爲根對象,所以訪問其他非根對象時,需要加#前綴。實際上,#相當於ActionContext. getContext();#session.msg表達式相當於ActionContext.getContext().getSession(). getAttribute("msg") 。

—    用於過濾和投影(projecting)集合,如persons.{?#this.age>25},persons.{?#this.name=='pla1'}.{age}[0]。

—    用來構造Map,例如示例中的#{'foo1':'bar1', 'foo2':'bar2'}。

2.%符號

%符號的用途是在標誌的屬性爲字符串類型時,計算OGNL表達式的值,這個類似js中的eval,很暴力。

3.$符號

$符號主要有兩個方面的用途。

—    在國際化資源文件中,引用OGNL表達式,例如國際化資源文件中的代碼:reg.agerange=國際化資源信息:年齡必須在${min}同${max}之間。

—    在Struts 2框架的配置文件中引用OGNL表達式,例如:

 

  1. <validators>    
  2.     <field name="intb">    
  3.             <field-validator type="int">    
  4.             <param name="min">10</param>    
  5.             <param name="max">100</param>    
  6.             <message>BAction-test校驗:數字必須爲${min}爲${max}之間!</message>    
  7.         </field-validator>    
  8.     </field>    
  9. </validators>   

總結OGNL的使用方法:

訪問屬性

名字屬性獲取:<s:property value="user.username"/><br>

地址屬性獲取:<s:property value="user.address.addr"/><br>

訪問方法

調用值棧中對象的普通方法:<s:property value="user.get()"/><br>

訪問靜態屬性和方法

調用Action中的靜態方法:<s:property value="@struts.action.LoginAction@get()"/>

調用JDK中的類的靜態方法:<s:property value="@java.lang.Math@floor(44.56)"/><br>

調用JDK中的類的靜態方法(同上):<s:property value="@@floor(44.56)"/><br>

調用JDK中的類的靜態方法:<s:property value="@java.util.Calendar@getInstance()"/><br>

調用普通類中的靜態屬性:<s:property value="@struts.vo.Address@TIPS"/><br>

訪問構造方法

調用普通類的構造方法:<s:property value="new struts.vo.Student('李曉紅' , '美女' , 3 , 25).username"/>

 

訪問數組

獲取List:<s:property value="testList"/><br>

獲取List中的某一個元素(可以使用類似於數組中的下標獲取List中的內容):

<s:property value="testList[0]"/><br>

獲取Set:<s:property value="testSet"/><br>

獲取Set中的某一個元素(Set由於沒有順序,所以不能使用下標獲取數據):

<s:property value="testSet[0]"/><br>

獲取Map:<s:property value="testMap"/><br>

獲取Map中所有的鍵:<s:property value="testMap.keys"/><br>

獲取Map中所有的值:<s:property value="testMap.values"/><br>

獲取Map中的某一個元素(可以使用類似於數組中的下標獲取List中的內容):

<s:property value="testMap['m1']"/><br>

獲取List的大小:<s:property value="testSet.size"/><br>

 

訪問集合 – 投影、選擇(? ^ $)

利用選擇獲取List中成績及格的對象:<s:property value="stus.{?#this.grade>=60}"/><br>

利用選擇獲取List中成績及格的對象的username:

<s:property value="stus.{?#this.grade>=60}.{username}"/><br>

利用選擇獲取List中成績及格的第一個對象的username:

<s:property value="stus.{?#this.grade>=60}.{username}[0]"/><br>

利用選擇獲取List中成績及格的第一個對象的username:

<s:property value="stus.{^#this.grade>=60}.{username}"/><br>

利用選擇獲取List中成績及格的最後一個對象的username:

<s:property value="stus.{$#this.grade>=60}.{username}"/><br>

利用選擇獲取List中成績及格的第一個對象然後求大小:

<s:property value="stus.{^#this.grade>=600}.{username}.size"/><br>

集合的僞屬性

OGNL能夠引用集合的一些特殊的屬性,這些屬性並不是JavaBean模式,例如size(),length()等等. 當表達式引用這些屬性時,OGNL會調用相應的方法,這就是僞屬性.

集合類型

僞屬性

Collection(inherited by Map, List ,Set)

size ,isEmpty

List

iterator

Map

keys , values

Set

iterator

Iterator

next , hasNext

Enumeration

next , hasNext , nextElement , hasMoreElements


 

 Lambda   :[…]

格式   :[…]

使用Lambda表達式計算階乘:

<s:property value="#f = :[#this==1?1:#this*#f(#this-1)] , #f(4)"/><br>

OGNL中#的使用

#可以取出堆棧上下文中的存放的對象.

名稱

作用

例子

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)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

獲取Paraments對象的屬性:<s:property value="#parameters.username"/>

OGNL中%的使用

用%{}可以取出存在值堆棧中的Action對象,直接調用它的方法.

例如你的Action如果繼承了ActionSupport .那麼在頁面標籤中,用%{getText('key')}的方式可以拿出國際化信息.

 OGNL中$的使用

“$”有兩個主要的用途

l         用於在國際化資源文件中,引用OGNL表達式

l         在Struts 2配置文件中,引用OGNL表達式

 值棧

ValueStack對象。這個對象貫穿整個Action的生命週期(每個Action類的對象實例會擁有一個ValueStack對象)。當 Struts 2接收到一個.action的請求後,會先建立Action類的對象實例,但並不會調用Action方法,而是先將Action類的相應屬性放到 ValueStack對象的頂層節點(ValueStack對象相當於一個棧)。

在Action中獲得ValueStack對象:ActionContext.getContext().getValueStack()

l         Top語法

使用Top獲取值棧中的第二個對象:<s:property value="[1].top.對象"/>

l         N語法

使用N獲取值棧中的第二個對象:<s:property value="[1].對象"/>

l         @語法

調用action中的靜態方法:<s:property value="@vs1@靜態方法"/> vs:值棧 1:表示第一個。

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