Struts2的OGNL表達式語言
OGNL是Object-GraphNavigation Language的縮寫,全稱爲對象圖導航語言,是一種功能強大的表達式語言,它通過簡單一致的語法,可以任意存取對象的屬性或者調用對象的方法,能夠遍歷整個對象的結構圖,實現對象屬性類型的轉換等功能。
-
OGNL表達式的計算是圍繞OGNL上下文進行的。OGNL上下文實際上就是一個Map對象,由ognl.OgnlContext類表示。它裏面可以存放很多個JavaBean對象。它有一個上下文根對象。上下文中的根對象可以直接使用名來訪問或直接使用它的屬性名訪問它的屬性值。否則要加前綴“#key”。
-
Struts2的標籤庫都是使用OGNL表達式來訪問ActionContext中的對象數據的。如:<s:propertyvalue="xxx"/>。
-
Struts2將ActionContext設置爲OGNL上下文,並將值棧作爲OGNL的根對象放置到ActionContext中。
-
值棧(ValueStack) : 可以在值棧中放入、刪除、查詢對象。訪問值棧中的對象不用“#”。Struts2總是把當前Action實例放置在棧頂。所以在OGNL中引用Action中的屬性也可以省略“#”。
-
調用ActionContext的put(key,value)放入的數據,需要使用#訪問。
OGNL中重要的3個符號:#、%、$:
#、%和$符號在OGNL表達式中經常出現,而這三種符號也是開發者不容易掌握和理解的部分,需要時間的積累才漸漸弄清楚……
-
#符號
#符號的用途一般有三種。
-
訪問非根對象屬性,例如#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'}。
-
-
%符號
%符號的用途是在標誌的屬性爲字符串類型時,計算OGNL表達式的值,這個類似js中的eval,很暴力。用%{}可以取出存在值堆棧中的Action對象,直接調用它的方法.
例如你的Action如果繼承了ActionSupport .那麼在頁面標籤中,用%{getText('key')}的方式可以拿出國際化信息.
-
$符號
$符號主要有兩個方面的用途。
-
在國際化資源文件中,引用OGNL表達式,例如國際化資源文件中的代碼:reg.agerange=國際化資源信息:年齡必須在${min}同${max}之間。
-
在Struts 2框架的配置文件中引用OGNL表達式,例如:
<validators> <field name="intb"> <field-validator type="int"> <param name="min">10</param> <param name="max">100</param> <message>BAction-tes校驗:數字必須爲${min}爲${max}之間!</message> </field-validator> </field> </validators>
-
使用#取出堆棧(Stack Context)上下文中的存放的對象
-
parameters對象:用於訪問HTTP請求參數。#parameters[‘foo’]或#parameters.foo,用於返回調用HttpServletRequest的getParameter(“foo”)方法的返回值。
-
request對象:用於訪問HttpServletRequest的屬性。例如#request[‘foo’]或# request.foo,用於返回調用HttpServletRequest的getAttribute(“foo”)方法的返回值。
-
session對象:用於訪問HttpSession的屬性。例如#session[‘foo’]或# session.foo,用於返回調用HttpSession的getAttribute(“foo”)方法的返回值。
-
application對象:用於訪問ServletContext的屬性。例如#application[‘foo’]或# application.foo,用於返回調用ServletContext的getAttribute(“foo”)方法的返回值。
-
attr對象:該對象將依次搜索如下對象:PageContext、HttpServletRequest、HttpSession、ServletContext中的屬性。也就是用於按request > session > application順序訪問其屬性(attribute)。
OGNL中的集合操作
-
直接生成List類型集合的語法:{e1,e2,e3,e4...}
//直接生成一個List類型集合,該集合包含了3個元素:e1,e2,e3和e4。如果需要多個元素,則多個元素直接用英文逗號隔開;
-
自己生成Map類型集合的語法:#{key1:value1,key2:value2,...}
//直接生成一個Map類型的集合,該Map對象中每個key-value對象之間以英文冒號隔開。多項之間以英文逗號隔開;
-
OGNL提供了兩個元素符:in 和 not in ,其中in判斷某個元素是否在指定集合中;not in 判斷是否不在某個集合中;
<s:if test=" 'name' in{'name','passwoed'} ">
"name"包含在集合裏
</s:if>
<s:else>
"name"不在集合裏
</s:else>
-
OGNL取得子集時有如下3個操作符:
? :取出所有符合選擇邏輯的元素
^ :取出符合選擇邏輯的第一個元素
$ :取出所有符合選擇邏輯的最後一個元素
例如: person.relatives.{? #this.gender == 'male'}
在上面代碼中,直接在集合後面緊跟 .{} 運算符表明用於取出該集合的子集,在{ }內使用?表明取出所有符合選擇邏輯的元素,而 #tihs 代表集合裏的元素。因此,上面代碼的含義是:取出person的所有性別爲male的relatives(親戚)集合;
訪問靜態成員(包括調用靜態方法、訪問靜態Field)
Struts2默認關閉了訪問靜態方法,打開方法:在struts.xml文件中增加如下代碼片段:
<!--設置允許OGNL允許訪問靜態成員 -->
<constantname=”struts.ognl.allowStaticMethodAccess”value=”true”>
一旦設置了上面所示常量,OGNL表達式可以通過如下語法來訪問靜態成員:
@className@staticField
@className@staticMethod(val...)
JSP頁面使用下面方式來訪問靜態Field和靜態方法:
訪問系統環境變量:
<s:propertyvalue=”@java.lang.System@getenv(‘JAVA_HOME’)”/><br/>
圓周率的值:<s:propertyvalue=”@java.lang.Math@PI”/>
Lambda表達式
格式::[…]
使用Lambda表達式計算階乘:
<s:property value="#f = :[#this==1?1:#this*#f(#this-1)] , #f(4)"/><br>