在上篇博客,咱們一塊兒看了《ognl概念和原理詳解》,咱們大約的知道了ognl的基本實現原理和一些基本概念,這節咱們一塊兒來學習一下OGNL表達式的基本語法和基本用法,首先咱們一塊兒來看一下OGNL中的#、%和$符號。html
一.OGNL中的#、%和$符號java
#、%和$符號在OGNL表達式中常常出現,而這三種符號也是開發者不容易掌握和理解的部分。在這裏咱們簡單介紹它們的相應用途。數據庫
1.#符號的三種用法express
1)訪問非根對象屬性,例如示例中的#session.msg表達式,因爲Struts 2中值棧被視爲根對象,因此訪問其餘非根對象時,須要加#前綴。實際上,#至關於ActionContext. getContext();#session.msg表達式至關於ActionContext.getContext().getSession(). getAttribute("msg") 。數組
2)用於過濾和投影(projecting)集合,如示例中的persons.{?#this.age>20}。session
3) 用來構造Map,例如示例中的#{'foo1':'bar1', 'foo2':'bar2'}。app
2.%符號框架
%符號的用途是在標誌的屬性爲字符串類型時,計算OGNL表達式的值。以下面的代碼所示:學習
<h3>構造Map</h3>this
<s:set name="foobar" value="#{'foo1':'bar1', 'foo2':'bar2'}" />
<p>The value of key "foo1" is <s:property value="#foobar['foo1']" /></p>
<p>不使用%:<s:url value="#foobar['foo1']" /></p>
<p>使用%:<s:url value="%{#foobar['foo1']}" /></p>
運行界面以下所示。
he value of key "foo1" is bar1
不使用%:#foobar['foo1']
使用%:bar1
3.$符號
$符號主要有兩個方面的用途。
1) 在國際化資源文件中,引用OGNL表達式,例如國際化資源文件中的代碼:reg.agerange=國際化資源信息:年齡必須在${min}同${max}之間。
2) 在Struts 2框架的配置文件中引用OGNL表達式,例以下面的代碼片段所示:
- <validators>
-
- <field name="intb">
-
- <field-validator type="int">
-
- <param name="min">10</param>
-
- <param name="max">100</param>
-
- <message>BAction-test校驗:數字必須爲${min}爲${max}之間!</message>
-
- </field-validator>
-
- </field>
-
- </validators>
二.咱們一塊兒看一下OGNL經常使用表達式:
1. 當使用OGNL調用靜態方法的時候,須要按照以下語法編寫表達式:
@package.classname@methodname(parameter)
2. 對於OGNL來講,java.lang.Math是其的默認類,若是調用java.lang.Math的靜態方法時,無需指定類的名字,好比:@@min(4, 10);
3. 對於OGNL來講,數組與集合是同樣的,都是經過下標索引來去訪問的。
獲取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> |
4. 使用OGNL來處理映射(Map)的語法格式以下所示:
#{‘key1’: ‘value1’, ‘key2’: ‘value2’, ‘key3’: ‘value3’};
5. 過濾(filtering):collection.{? expression}
6. OGNL針對集合提供了一些僞屬性(如size,isEmpty),讓咱們能夠經過屬性的方式來調用方法(本質緣由在於集合當中的不少方法並不符合JavaBean的命名規則),但我麼你依然還能夠經過調用方法來實現與僞屬性相同的目的。
7. 過濾(filtering),獲取到集合中的第一個元素:collection.{^ expression}
8. 過濾(filtering),獲取到集合中的最後一個元素:collection.{& expression}
9. 在使用過濾操做時,咱們一般都會使用#this,該表達式用於表明當前正在迭代的集合中的對象(聯想加強的for循環)
10. 投影(projection):collection.{expression}
11. 過濾與投影之間的差異:類比於數據庫中的表,過濾是取行的操做,而投影是取列的操做。 具體舉例以下:
利用選擇獲取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> |
12. 在Struts2中,根對象就是ValueStack。在Struts2的任何流程當中,ValueStack中的最頂層對象必定是Action對象。
13. parameters,#parameters.username
request, #request.username
session, #session.username
application, #application.username
attr, #attr.username
以上幾個對象叫作「命名對象」。
14. 訪問靜態方法或是靜態成員變量的改進。
@vs @method
15. 關於Struts2標籤庫屬性值的%與#號的關係:
1). 若是標籤的屬性值是OGNL表達式,那麼無需加上%{}。
2). 若是標籤的屬性值是字符串類型,那麼在字符串當中凡是出現的%{}都會被解析成OGNL表達式,解析完畢後再與其餘的字符串進行拼接構造出最後的字符串值。
3). 咱們能夠在全部的屬性值上加%{},這樣若是該屬性值是OGNL表達式,那麼標籤處理類就會將%{}忽略掉。
最後一塊兒用代碼說話,簡單的看一下ognl操做的示例:
1)上下文環境中使用OGNL
- public static void main(String[] args)
- {
- /* 建立一個上下文Context對象,它是用保存多個對象一個環境 對象*/
- Map<String , Object> context = new HashMap<String , Object>();
-
- Person person1 = new Person();
- person1.setName("zhangsan");
-
- Person person2 = new Person();
- person2.setName("lisi");
-
- Person person3 = new Person();
- person3.setName("wangwu");
-
- /* person4不放入到上下文環境中*/
- Person person4 = new Person();
- person4.setName("zhaoliu");
-
- /* 將person一、person二、person3添加到環境中(上下文中)*/
- context.put("person1", person1);
- context.put("person2", person2);
- context.put("person3", person3);
-
- try
- {
- /* 獲取根對象的"name"屬性值*/
- Object value = Ognl.getValue("name", context, person2);
- System.out.println("ognl expression \"name\" evaluation is : " + value);
-
- /* 獲取根對象的"name"屬性值*/
- Object value2 = Ognl.getValue("#person2.name", context, person2);
- System.out.println("ognl expression \"#person2.name\" evaluation is : " + value2);
-
- /* 獲取person1對象的"name"屬性值*/
- Object value3 = Ognl.getValue("#person1.name", context, person2);
- System.out.println("ognl expression \"#person1.name\" evaluation is : " + value3);
-
- /* 將person4指定爲root對象,獲取person4對象的"name"屬性,注意person4對象不在上下文中*/
- Object value4 = Ognl.getValue("name", context, person4);
- System.out.println("ognl expression \"name\" evaluation is : " + value4);
-
- /* 將person4指定爲root對象,獲取person4對象的"name"屬性,注意person4對象不在上下文中*/
- Object value5 = Ognl.getValue("#person4.name", context, person4);
- System.out.println("ognl expression \"person4.name\" evaluation is : " + value5);
-
- /* 獲取person4對象的"name"屬性,注意person4對象不在上下文中*/
- // Object value6 = Ognl.getValue("#person4.name", context, person2);
- // System.out.println("ognl expression \"#person4.name\" evaluation is : " + value6);
-
- }
2)使用OGNL調用方法
- public static void main(String[] args)
- {
- /* OGNL提供的一個上下文類,它實現了Map接口*/
- OgnlContext context = new OgnlContext();
-
- People people1 = new People();
- people1.setName("zhangsan");
-
- People people2 = new People();
- people2.setName("lisi");
-
- People people3 = new People();
- people3.setName("wangwu");
-
- context.put("people1", people1);
- context.put("people2", people2);
- context.put("people3", people3);
-
- context.setRoot(people1);
-
- try
- {
- /* 調用 成員方法*/
- Object value = Ognl.getValue("name.length()", context, context.getRoot());
- System.out.println("people1 name length is :" + value);
-
- Object upperCase = Ognl.getValue("#people2.name.toUpperCase()", context, context.getRoot());
- System.out.println("people2 name upperCase is :" + upperCase);
-
- Object invokeWithArgs = Ognl.getValue("name.charAt(5)", context, context.getRoot());
- System.out.println("people1 name.charAt(5) is :" + invokeWithArgs);
-
- /* 調用靜態方法*/
- Object min = Ognl.getValue("@java.lang.Math@min(4,10)", context, context.getRoot());
- System.out.println("min(4,10) is :" + min);
-
- /* 調用靜態變量*/
- Object e = Ognl.getValue("@java.lang.Math@E", context, context.getRoot());
- System.out.println("E is :" + e);
- }
3)使用OGNL操做集合
- public static void main(String[] args) throws Exception
- {
- OgnlContext context = new OgnlContext();
-
- Classroom classroom = new Classroom();
- classroom.getStudents().add("zhangsan");
- classroom.getStudents().add("lisi");
- classroom.getStudents().add("wangwu");
- classroom.getStudents().add("zhaoliu");
- classroom.getStudents().add("qianqi");
-
- Student student = new Student();
- student.getContactWays().put("homeNumber", "110");
- student.getContactWays().put("companyNumber", "119");
- student.getContactWays().put("mobilePhone", "112");
-
- context.put("classroom", classroom);
- context.put("student", student);
- context.setRoot(classroom);
-
- /* 得到classroom的students集合*/
- Object collection = Ognl.getValue("students", context, context.getRoot());
- System.out.println("students collection is :" + collection);
-
- /* 得到classroom的students集合*/
- Object firstStudent = Ognl.getValue("students[0]", context, context.getRoot());
- System.out.println("first student is : " + firstStudent);
-
- /* 調用集合的方法*/
- Object size = Ognl.getValue("students.size()", context, context.getRoot());
- System.out.println("students collection size is :" + size);
-
- System.out.println("--------------------------飄逸的分割線--------------------------");
-
- Object mapCollection = Ognl.getValue("#student.contactWays", context, context.getRoot());
- System.out.println("mapCollection is :" + mapCollection);
-
- Object firstElement = Ognl.getValue("#student.contactWays['homeNumber']", context, context.getRoot());
- System.out.println("the first element of contactWays is :" + firstElement);
-
- System.out.println("--------------------------飄逸的分割線--------------------------");
-
- /* 建立集合*/
- Object createCollection = Ognl.getValue("{'aa','bb','cc','dd'}", context, context.getRoot());
- System.out.println(createCollection);
-
- /* 建立Map集合*/
- Object createMapCollection = Ognl.getValue("#{'key1':'value1','key2':'value2'}", context, context.getRoot());
- System.out.println(createMapCollection);
-
- }
- }