OGNL 學習、開發與實踐

OGNL 的歷史

OGNL 最初是爲了能夠使用對象的屬性名來建立 UI 組件 (component) 和 控制器 (controllers) 之間的聯繫,簡單來說就是:視圖 與 控制器 之間數據的聯繫。後來爲了應付更加複雜的數據關係,Drew Davidson 發明了一個被他稱爲 KVCL(Key-Value Coding Language) 的語言。 Luke 參與進來後,用 ANTLR 來實現了該語言,並給它取了這個新名字,他後來又使用 JavaCC 重新實現了該語言。目前 OGNL 由 Drew 來負責維護。目前很多項目中都用到了 OGNL,其中不乏爲大家所熟知的,例如幾個流行的 web 應用框架:WebWork,Tapestry 等。

什麼是 OGNL?

OGNL 是 Object-Graph Navigation Language 的縮寫,從語言角度來說:它是一個功能強大的表達式語言,用來獲取和設置 java 對象的屬性 , 它旨在提供一個更高抽象度語法來對 java 對象圖進行導航,OGNL 在許多的地方都有應用,例如:

  1. 作爲 GUI 元素(textfield,combobox, 等)到模型對象的綁定語言。
  2. 數據庫表到 Swing 的 TableModel 的數據源語言。
  3. web 組件和後臺 Model 對象的綁定語言 (WebOGNL,Tapestry,WebWork,WebObjects) 。
  4. 作爲 Jakarata Commons BeanUtils 或者 JSTL 的表達式語言的一個更具表達力的替代語言。

另外,java 中很多可以做的事情,也可以使用 OGNL 來完成,例如:列表映射和選擇。對於開發者來說,使用 OGNL,可以用簡潔的語法來完成對 java 對象的導航。通常來說:通過一個“路徑”來完成對象信息的導航,這個“路徑”可以是到 java bean 的某個屬性,或者集合中的某個索引的對象,等等,而不是直接使用 get 或者 set 方法來完成。


爲什麼需要表達式語言 (EL)

表達式語言(EL)本質上被設計爲:幫助你使用簡單的表達式來完成一些“常用”的工作。通常情況下,ELs 可以在一些框架中找到,它被是用來簡化我們的工作。例如:大家熟知的 Hibernate,使用 HQL(Hibernate Query Language) 來完成數據庫的操作,HQL 成了開發人員與複查的 SQL 表達式之間的一個橋樑。在 web 框架下,表達式語言起到了相似的目的。它的存在消除了重複代碼的書寫。例如:當沒有 EL 的時候,爲了從 session 中得到購物車並且將 ID 在網頁上呈現出來,當直接在 jsp 中使用 java 代碼來完成的時候,一般是:


<% 
    ShoppingCart cart = (ShoppingCart) session.get("cart"); 
    int id = cart.getId(); 
    %> 
    <%= id%>

你也可以將這些 code 壓縮成一句,如下,但是現在代碼就很不直觀,且不可讀。另外,雖然變成了一句,但是與上面的原始的例子一樣,也包含了同樣的表達式。例如:類型轉換:轉換成 ShoppingCart 。這裏只不過是將原來的三個表達式變成了一句,其複雜度是沒有得到簡化的。


<%= ((ShoppingCart) session.get("cart")).getId() %>

當在 web 框架中使用表達式語言的時候,則可以有效的處理這種代碼的複雜性。而不需要你,調用 servelet API,類型轉換,然後再調用 getter 方法,多數的 Els 都可將這個過程簡化爲類似於:#session.cart.id 這中更可讀的表達式。表達式:#session.cart.id 與 java 代碼不一樣的是:沒有 java 代碼的 get 方法調用和類型轉換。因爲這些操作是非常“常用”的,這時候使用 EL 就順理成章了,使用 EL 可以“消除”這些代碼。


OGNL 的基本語法

OGNL 表達式一般都很簡單。雖然 OGNL 語言本身已經變得更加豐富了也更強大了,但是一般來說那些比較複雜的語言特性並未影響到 OGNL 的簡潔:簡單的部分還是依然那麼簡單。比如要獲取一個對象的 name 屬性,OGNL 表達式就是 name, 要獲取一個對象的 headline 屬性的 text 屬性,OGNL 表達式就是 headline.text 。 OGNL 表達式的基本單位是“導航鏈”,往往簡稱爲“鏈”。最簡單的鏈包含如下部分:

表達式組成部分示例
屬性名稱 如上述示例中的 name 和 headline.text
方法調用 hashCode() 返回當前對象的哈希碼。
數組元素 listeners[0] 返回當前對象的監聽器列表中的第一個元素。

所有的 OGNL 表達式都基於當前對象的上下文來完成求值運算,鏈的前面部分的結果將作爲後面求值的上下文。你的鏈可以寫得很長,例如:


name.toCharArray()[0].numericValue.toString()

上面的表達式的求值步驟:

  • 提取根 (root) 對象的 name 屬性。
  • 調用上一步返回的結果字符串的 toCharArray() 方法。
  • 提取返回的結果數組的第一個字符。
  • 獲取字符的 numericValue 屬性,該字符是一個 Character 對象,Character 類有一個 getNumericValue() 方法。
  • 調用結果 Integer 對象的 toString() 方法。

上面的例子只是用來得到一個對象的值,OGNL 也可以用來去設置對象的值。當把上面的表達式傳入 Ognl.setValue() 方法將導致 InappropriateExpressionException,因爲鏈的最後的部分(toString())既不是一個屬性的名字也不是數組的某個元素。瞭解了上面的語法基本上可以完成絕大部分工作了。


如何使用 OGNL

OGNL 不僅能夠去獲取或者設置對象的屬性,而也可以用來:完成實例方法的調用,靜態方法的調用,表達式求值,Lambda 表達式等,下面我們看看如何使用 OGNL 來完成這些任務。

ognl.Ognl

最簡單的使用是直接使用 ognl.Ognl 類來評估一個 OGNL 表達式。 Ognl 類提供一些靜態方法用來解析和解釋 OGNL 表達式,最簡單的示例是不使用上下文從一個對象中獲取某個表達式的值,示例如下:


import ognl.Ognl; import ognl.OgnlException; 
 try { 
 result = Ognl.getValue(expression, root);  
 }    
 catch (OgnlException ex)    
 {   // Report error or recover   }

上述代碼將基於 root 對象評估 expression,返回結果,如果表達式有錯,比如沒有找到指定的屬性,將拋出 OgnlException 。更復雜一點的應用是使用預解析的表達式。這種方式允許在表達式求值之前就能捕獲表達式的解析錯誤,應用開發人員可以緩存表達式解析出來的結果(AST),從而能在重複使用的時候提高性能。 Ognl 的 parseExpression 方法就是用來執行預解析操作的。 Ognl 2.7 版本後由於添加了“ Expression Compilation ”性能得到了質的提高,在後面章節會有介紹。 Ognl 類的獲取和設置方法也可以接受一個 context map 參數,他允許你放一些自己的變量,並能在 Ognl 表達式中使用。缺省的上下文裏只包含 #root 和 #context 兩個鍵。下面的示例展示如何從 root 對象中解析出 documentName 屬性,然後將當前用戶名稱添加到返回的結果後面:


private Map context = new HashMap();    
  public void setUserName(String value)   
  {   
      context.put("userName", value);   
  }   
  try {   
     // get value using our own custom context map   
     result = Ognl.getValue("userName"", context, root);   
  } catch (OgnlException ex) {   
      // Report error or recover   
  }

上面提到的 #root 變量指向的就是當前的 root 變量(表達式求值的初始對象(initial object)), 而 #context 就是指向的 Map 對象,下面的例子可以更直觀的說明


 User root = new User(); 
     root.setId(19612); 
     root.setName("sakura");     
     Map context = new HashMap(); 
     context.put("who", "Who am i?");   
     try {       
       String who1 = (String)Ognl.getValue("#who", context, root);   
       String who2 = (String)Ognl.getValue("#context.who", context, root); 
         Object whoExp = Ognl.parseExpression("#who"); 
       String who3 = (String)Ognl.getValue(whoExp, context, root); 
       //who1 who2 who3 返回同樣的值, whoExp 重複使用可以提高效率        
       String name1 = (String)Ognl.getValue("name", root); 
       String name2 = (String)Ognl.getValue("#root.name", root);    
       
       //name1 name2 返回同樣的值
     } catch (OgnlException e) { 
       //error handling 
     }

OGNL 表達式

  1. 常量:字符串:“ hello ” 字符:‘ h ’ 數字:除了像 java 的內置類型 int,long,float 和 double,Ognl 還有如例:10.01B,相當於 java.math.BigDecimal,使用’ b ’或者’ B ’後綴。 100000H,相當於 java.math.BigInteger,使用’ h ’ 或 ’ H ’ 後綴。
  2. 屬性的引用例如:user.name
  3. 變量的引用例如:#name
  4. 靜態變量的訪問使用 @class@field
  5. 靜態方法的調用使用 @class@method(args), 如果沒有指定 class 那麼默認就使用 java.lang.Math.
  6. 構造函數的調用例如:new java.util.ArrayList();

其它的 Ognl 的表達式可以參考 Ognl 的語言手冊。

OGNL 的基本用法

OGNL 的 API,前面我們已經介紹過了,OGNL 的一個主要功能就是對象圖的導航,我們看一下 OGNL 的最基本的用去取值和設置的 API


getValue

public static java.lang.Object getValue(java.lang.String expression, 
                                            java.util.Map context, 
                                            java.lang.Object root, 
                                            java.lang.Class resultType) 
                                     throws OgnlException 
     Evaluates the given OGNL expression to extract a value 
      from the given root object in a given context 
     Parameters: 
     expression - the OGNL expression to be parsed 
     context - the naming context for the evaluation 
     root - the root object for the OGNL expression 
     resultType - the converted type of the resultant object, 
                 using the context's type converter 
     Returns: 
     the result of evaluating the expression


setValue
    public static void setValue(java.lang.String expression, 
                                 java.util.Map context, 
                                 java.lang.Object root, 
                                 java.lang.Object value) 
                          throws OgnlException 
     Evaluates the given OGNL expression to insert a value into the 
     object graph rooted at the given root object given the context. 
     Parameters: 
     expression - the OGNL expression to be parsed 
     root - the root object for the OGNL expression 
     context - the naming context for the evaluation 
     value - the value to insert into the object graph

OGNL 的 API 設計得是很簡單的,context 提供上下文,爲變量和表達式的求值過程來提供命名空間,存儲變量 等,通過 root 來指定對象圖遍歷的初始變量,使用 expression 來告訴 Ognl 如何完成運算。看看下面兩個簡單的代碼片段:/


User user1 = new User(); 
user1.setId(1); 
user1.setName("firer"); 		
User user2 = new User(); 
user2.setId(2); 
user2.setName("firer2"); 		
List users = new ArrayList(); 
users.add(user1); 
users.add(user2); 		
Department dep = new Department(); 
dep.setUsers(users); 
dep.setName("dep"); 
dep.setId(11); 		
Object o = Ognl.getValue("users[1].name", dep);

這裏我們可以看到前面介紹的使用表達式語言的有點,使用 "users[1].name",就能完成對 name 的取值,而不用去進行類型轉換等工作。下面是一個簡單的設值的例子。


User user = new User(); 
user.setId(1); 
user.setName("ffirer"); 		
Ognl.setValue("department.name", user, "dep1");

就想前面介紹的,Ognl 也可以完成一些其它的工作,一個例子就是在我們的日常工作中,我們經常需要從列表中去“搜索”符合我們要求的對象,使用 java 的時候我們需要對列表進行遍歷、類型轉換、取值然後比較來得到我們想要的值,而使用 Ognl 將使這個過程變得簡單,優雅。代碼片段:


User user1 = new User(); 
 user1.setId(1); 
 user1.setName("firer"); 
 // 如上例創建一些 User 
 List users = new ArrayList(); 
 users.add(user1); 
 // 將創建的 User 添加到 List 中
 Department dep = new Department(); 
 dep.setUsers(users); 
 List names = (List)Ognl.getValue("users.{name}", dep); 
 List ids = (List)Ognl.getValue("users.{? #this.id > 1}", dep);

這裏表達式 "users.{name}" 將取得列表中所有 Users 的 name 屬性,並以另外一個列表返回。 "users.{? #this.id > 1}" 將返回所有 id 大於 1 的 User,也以一個列表返回,包含了所有的 User 對象。這裏使用的是 Ognl 的“列表投影”操作,叫這個名字是因爲比較像數據庫中返回某些列的操作。 Ognl 還有很多其它功能,在 Ognl 的 SVN(http://svn.opensymphony.com/svn/ognl/trunk)的 testcase 中找到如何使用它們。


OGNL 的性能

OGNL,或者說表達式語言的性能主要又兩方面來決定,一個就是對錶達式的解析 (Parser),另一個是表達式的執行,OGNL 採用 javaCC 來完成 parser 的實現,在 OGNL 2.7 中又對 OGNL 的執行部分進行了加強,使用 javasisit 來 JIT(Just-In-Time) 的生成 byte code 來完成表達式的執行。 Ognl 給這個功能的名字是:OGNL Expression Compilation 。基本的使用方法是:


SimpleObject root = new SimpleObject(); 
 OgnlContext context =  (OgnlContext) Ognl.createDefaultContext(null); 

 Node node =  (Node) Ognl.compileExpression(context, root, "user.name"); 
 String userName = (String)node.getAccessor().get(context, root);

那麼使用 Expression Compilation 能給 Ognl 的性能帶來什麼了?一個性能方面的簡單測試:對比了 4 中情況:分別是:直接 Java 調用 (1), OGNL 緩存使用 expression compilation (2), OGNL 緩存使用 OGNL expression parsed(3) 以及不使用任何緩存的結果(4)。


圖 1. 性能對比

可以看到 expression compilation 非常接近使用 java 調用的時間,所以可以看到當表達式要被多次使用,使用 expression compilation 並且已經做好了緩存的情況下,OGNL 非常接近 java 直接調用的時間。

結束語

本文介紹了 OGNL 的概念、表達式語法以及如何使用 OGNL, 並提供了一些簡單的示例代碼,OGNL 在實際應用中還可以對其進行擴展,在本文中併爲涉及, 感興趣的讀者可以進一步進行相關的學習和研究

 

 

ognl 方法總結

 

Java代碼
  1. // ***************** root對象的概念 ******************* //   
  2. public void testOgnl_01() throws Exception{   
  3.     User user = new User();   
  4.     user.setUsername("張三");   
  5.        
  6.     //相當於調用user.getUsername()方法   
  7.     String value = (String)Ognl.getValue("username", user);   
  8.     System.out.println(value);   
  9. }   
  10.   
  11. public void testOgnl_02() throws Exception{   
  12.     User user = new User();   
  13.     Person p = new Person();   
  14.     p.setName("張三");   
  15.     user.setPerson(p);   
  16.        
  17.     //相當於調用user.getPerson().getName()方法   
  18.     String value = (String)Ognl.getValue("person.name", user);   
  19.     System.out.println(value);   
  20. }   
  21.   
  22. public void testOgnl_03() throws Exception{   
  23.     User user = new User();   
  24.     Person p = new Person();   
  25.     p.setName("張三");   
  26.     user.setPerson(p);   
  27.        
  28.     //可以使用#root來引用根對象,相當於調用user.getPerson().getName()方法   
  29.     String value = (String)Ognl.getValue("#root.person.name", user);   
  30.     System.out.println(value);   
  31. }   
	// ***************** root對象的概念 ******************* //
public void testOgnl_01() throws Exception{
User user = new User();
user.setUsername("張三");
//相當於調用user.getUsername()方法
String value = (String)Ognl.getValue("username", user);
System.out.println(value);
}
public void testOgnl_02() throws Exception{
User user = new User();
Person p = new Person();
p.setName("張三");
user.setPerson(p);
//相當於調用user.getPerson().getName()方法
String value = (String)Ognl.getValue("person.name", user);
System.out.println(value);
}
public void testOgnl_03() throws Exception{
User user = new User();
Person p = new Person();
p.setName("張三");
user.setPerson(p);
//可以使用#root來引用根對象,相當於調用user.getPerson().getName()方法
String value = (String)Ognl.getValue("#root.person.name", user);
System.out.println(value);
}

 

 

 

Java代碼
  1. // *********************** context的概念 **********************//   
  2.     public void testOgnl_04() throws Exception{   
  3.         Person p1 = new Person();   
  4.         Person p2 = new Person();   
  5.         p1.setName("張三");   
  6.         p2.setName("李四");   
  7.            
  8.         Map context = new HashMap();   
  9.         context.put("p1", p1);   
  10.         context.put("p2", p2);   
  11.            
  12.         String value = (String)Ognl.getValue("#p1.name + ',' + #p2.name", context, new Object());   
  13.         System.out.println(value);   
  14.     }   
  15.        
  16.     public void testOgnl_05() throws Exception{   
  17.         Person p1 = new Person();   
  18.         Person p2 = new Person();   
  19.         p1.setName("張三");   
  20.         p2.setName("李四");   
  21.            
  22.         Map context = new HashMap();   
  23.         context.put("p1", p1);   
  24.         context.put("p2", p2);   
  25.            
  26.         User root = new User();   
  27.         root.setUsername("zhangsan");   
  28.            
  29.         String value = (String)Ognl.getValue("#p1.name + ',' + #p2.name + ',' + username", context, root);   
  30.         System.out.println(value);   
  31.     }  
// *********************** context的概念 **********************//
public void testOgnl_04() throws Exception{
Person p1 = new Person();
Person p2 = new Person();
p1.setName("張三");
p2.setName("李四");
Map context = new HashMap();
context.put("p1", p1);
context.put("p2", p2);
String value = (String)Ognl.getValue("#p1.name + ',' + #p2.name", context, new Object());
System.out.println(value);
}
public void testOgnl_05() throws Exception{
Person p1 = new Person();
Person p2 = new Person();
p1.setName("張三");
p2.setName("李四");
Map context = new HashMap();
context.put("p1", p1);
context.put("p2", p2);
User root = new User();
root.setUsername("zhangsan");
String value = (String)Ognl.getValue("#p1.name + ',' + #p2.name + ',' + username", context, root);
System.out.println(value);
}

 

 

 

Java代碼
  1. // ******************* OGNL賦值操作 ************************//   
  2. public void testOgnl_06() throws Exception{   
  3.     User user = new User();   
  4.        
  5.     //給root對象的屬性賦值,相當於調用user.setUsername()   
  6.     Ognl.setValue("username", user, "zhangsan");   
  7.        
  8.     System.out.println(user.getUsername());   
  9. }   
  10.   
  11. public void testOgnl_07() throws Exception{   
  12.     User user = new User();   
  13.        
  14.     Map context = new HashMap();   
  15.     context.put("u", user);   
  16.        
  17.     //給context中的對象屬性賦值,相當於調用user.setUsername()   
  18.     Ognl.setValue("#u.username",context, new Object(), "zhangsan");   
  19.        
  20.     System.out.println(user.getUsername());   
  21. }   
  22.   
  23. public void testOgnl_08() throws Exception{   
  24.     User user = new User();   
  25.        
  26.     Map context = new HashMap();   
  27.     context.put("u", user);   
  28.        
  29.     //給context中的對象屬性賦值,相當於調用user.setUsername()   
  30.     //在表達式中使用=賦值操作符來賦值   
  31.     Ognl.getValue("#u.username = '張三'",context, new Object());   
  32.        
  33.     System.out.println(user.getUsername());   
  34. }   
  35.   
  36. public void testOgnl_09() throws Exception{   
  37.     User user = new User();   
  38.     Person p = new Person();   
  39.        
  40.     Map context = new HashMap();   
  41.     context.put("u", user);   
  42.        
  43.     context.put("p", p);   
  44.        
  45.     //給context中的對象屬性賦值,相當於調用user.setUsername()   
  46.     //在表達式中使用=賦值操作符來賦值   
  47.     Ognl.getValue("#u.username = '張三',#p.name = '李四'",context, new Object());   
  48.        
  49.     System.out.println(user.getUsername()+","+p.getName());   
  50. }   
	// ******************* OGNL賦值操作 ************************//
public void testOgnl_06() throws Exception{
User user = new User();
//給root對象的屬性賦值,相當於調用user.setUsername()
Ognl.setValue("username", user, "zhangsan");
System.out.println(user.getUsername());
}
public void testOgnl_07() throws Exception{
User user = new User();
Map context = new HashMap();
context.put("u", user);
//給context中的對象屬性賦值,相當於調用user.setUsername()
Ognl.setValue("#u.username",context, new Object(), "zhangsan");
System.out.println(user.getUsername());
}
public void testOgnl_08() throws Exception{
User user = new User();
Map context = new HashMap();
context.put("u", user);
//給context中的對象屬性賦值,相當於調用user.setUsername()
//在表達式中使用=賦值操作符來賦值
Ognl.getValue("#u.username = '張三'",context, new Object());
System.out.println(user.getUsername());
}
public void testOgnl_09() throws Exception{
User user = new User();
Person p = new Person();
Map context = new HashMap();
context.put("u", user);
context.put("p", p);
//給context中的對象屬性賦值,相當於調用user.setUsername()
//在表達式中使用=賦值操作符來賦值
Ognl.getValue("#u.username = '張三',#p.name = '李四'",context, new Object());
System.out.println(user.getUsername()+","+p.getName());
}

 

 

 

Java代碼
  1.   
  2. //****************** 使用OGNL調用對象的方法 **********************//   
  3. public void testOgnl_10() throws Exception{   
  4.     User user = new User();   
  5.     user.setUsername("張三");   
  6.        
  7.     String value = (String)Ognl.getValue("getUsername()", user);   
  8.     System.out.println(value);   
  9. }   
  10.   
  11. public void testOgnl_11() throws Exception{   
  12.     User user = new User();   
  13.        
  14.     Ognl.getValue("setUsername('張三')", user);   
  15.     System.out.println(user.getUsername());   
  16. }   
//****************** 使用OGNL調用對象的方法 **********************//
public void testOgnl_10() throws Exception{
User user = new User();
user.setUsername("張三");
String value = (String)Ognl.getValue("getUsername()", user);
System.out.println(value);
}
public void testOgnl_11() throws Exception{
User user = new User();
Ognl.getValue("setUsername('張三')", user);
System.out.println(user.getUsername());
}

 

 

 

Java代碼
  1. // ********************* OGNL中的this表達式 **********************//   
  2. public void testOgnl_14() throws Exception{   
  3.     Object root = new Object();   
  4.     Map context = new HashMap();   
  5.        
  6.     List values = new ArrayList();   
  7.     for(int i=0; i<11; i++){   
  8.         values.add(i);   
  9.     }   
  10.     context.put("values", values);   
  11.        
  12.     Ognl.getValue("@[email protected](#values.size.(#this > 10 ? /"大於10/" : '不大於10'))", context, root);   
  13.        
  14. }   
  15.   
  16. public void testOgnl_15() throws Exception{   
  17.     User user = new User();   
  18.        
  19.     Ognl.getValue("setUsername('ZHANGSAN')", user);   
  20.     Ognl.getValue("@[email protected](#this.username)", user);   
  21. }   
  22.   
  23. public void testOgnl_16() throws Exception{   
  24.     User user = new User();   
  25.        
  26.     Ognl.getValue("setUsername('ZHANGSAN')", user);   
  27.     Ognl.getValue("@[email protected](username.(#this.toLowerCase()))", user);   
  28. }  
	// ********************* OGNL中的this表達式 **********************//
public void testOgnl_14() throws Exception{
Object root = new Object();
Map context = new HashMap();
List values = new ArrayList();
for(int i=0; i<11; i++){
values.add(i);
}
context.put("values", values);
Ognl.getValue("@[email protected](#values.size.(#this > 10 ? /"大於10/" : '不大於10'))", context, root);
}
public void testOgnl_15() throws Exception{
User user = new User();
Ognl.getValue("setUsername('ZHANGSAN')", user);
Ognl.getValue("@[email protected](#this.username)", user);
}
public void testOgnl_16() throws Exception{
User user = new User();
Ognl.getValue("setUsername('ZHANGSAN')", user);
Ognl.getValue("@[email protected](username.(#this.toLowerCase()))", user);
}

 

 

 

Java代碼
  1. // ******************* 如何把表達式的解釋結果作爲另外一個表達式,OGNL中括號的使用 **********************//   
  2. public void testOgnl_17() throws Exception{   
  3.     Object root = new Object();   
  4.     Map context = new HashMap();   
  5.     User u = new User();   
  6.     u.setUsername("張三");   
  7.     context.put("u", u);   
  8.     context.put("fact""username");   
  9.        
  10.     /**  
  11.      * 1、首先把#fact表達式進行解釋,得到一個值:username  
  12.      * 2、解釋括號中的表達式#u,其結果是user對象  
  13.      * 3、把括號中表達式的結果作爲root對象,解釋在第一步中得到的結果(即把第一步的結果看成另外一個表達式)   
  14.      */  
  15.     String value = (String)Ognl.getValue("#fact(#u)", context, root);   
  16.     System.out.println(value);   
  17. }   
  18.   
  19. public void testOgnl_18() throws Exception{   
  20.     Person person = new Person();   
  21.     Map context = new HashMap();   
  22.     User u = new User();   
  23.     u.setUsername("張三");   
  24.     context.put("u", u);   
  25.        
  26.     /**  
  27.      * 相當於調用person這個根對象的fact方法,並把#u的解釋結果作爲參數傳入此方法   
  28.      */  
  29.     String value = (String)Ognl.getValue("fact(#u)", context, person);   
  30.     System.out.println(value); //輸出是 "張三,"   
  31. }   
  32.   
  33. public void testOgnl_19() throws Exception{   
  34.     Person person = new Person();   
  35.     Map context = new HashMap();   
  36.     User u = new User();   
  37.     u.setUsername("張三");   
  38.     context.put("u", u);   
  39.        
  40.     /**  
  41.      * 1、先計算表達式fact,得到結果是:username  
  42.      * 2、解釋括號中的表達式#u,其結果是user對象  
  43.      * 3、把括號中表達式的結果作爲root對象,解釋在第一步中得到的結果(即把第一步的結果看成另外一個表達式)  
  44.      */  
  45.     String value = (String)Ognl.getValue("(fact)(#u)", context, person);   
  46.     System.out.println(value); //輸出"張三"   
  47. }   
	// ******************* 如何把表達式的解釋結果作爲另外一個表達式,OGNL中括號的使用 **********************//
public void testOgnl_17() throws Exception{
Object root = new Object();
Map context = new HashMap();
User u = new User();
u.setUsername("張三");
context.put("u", u);
context.put("fact", "username");
/**
* 1、首先把#fact表達式進行解釋,得到一個值:username
* 2、解釋括號中的表達式#u,其結果是user對象
* 3、把括號中表達式的結果作爲root對象,解釋在第一步中得到的結果(即把第一步的結果看成另外一個表達式)
*/
String value = (String)Ognl.getValue("#fact(#u)", context, root);
System.out.println(value);
}
public void testOgnl_18() throws Exception{
Person person = new Person();
Map context = new HashMap();
User u = new User();
u.setUsername("張三");
context.put("u", u);
/**
* 相當於調用person這個根對象的fact方法,並把#u的解釋結果作爲參數傳入此方法
*/
String value = (String)Ognl.getValue("fact(#u)", context, person);
System.out.println(value); //輸出是 "張三,"
}
public void testOgnl_19() throws Exception{
Person person = new Person();
Map context = new HashMap();
User u = new User();
u.setUsername("張三");
context.put("u", u);
/**
* 1、先計算表達式fact,得到結果是:username
* 2、解釋括號中的表達式#u,其結果是user對象
* 3、把括號中表達式的結果作爲root對象,解釋在第一步中得到的結果(即把第一步的結果看成另外一個表達式)
*/
String value = (String)Ognl.getValue("(fact)(#u)", context, person);
System.out.println(value); //輸出"張三"
}

 

 

 

 

 

Java代碼
  1. // ********************* OGNL訪問集合元素 **************************//   
  2. public void testOgnl_20() throws Exception{   
  3.     Object root = new Object();   
  4.     Map context = new HashMap();   
  5.        
  6.     //用OGNL創建List對象   
  7.     List listvalue = (List)Ognl.getValue("{123,'kdjfk','oooo'}", context, root);   
  8.     context.put("listvalue", listvalue);   
  9.        
  10.     //用OGNL創建數組   
  11.     int[] intarray= (int[])Ognl.getValue("new int[]{23,45,67}", context, root);   
  12.     context.put("intarray", intarray);   
  13.        
  14.     //用OGNL創建Map對象   
  15.     Map mapvalue = (Map)Ognl.getValue("#{'listvalue':#listvalue,'intarray':#intarray}", context, root);   
  16.     context.put("mapvalue", mapvalue);   
  17.        
  18.     Ognl.getValue("@[email protected](#listvalue[0])", context, root);   
  19.     Ognl.getValue("@[email protected](#intarray[1])", context, root);   
  20.     Ognl.getValue("@[email protected](#mapvalue['intarray'][2])", context, root);   
  21.     Ognl.getValue("@[email protected](#mapvalue.intarray[0])", context, root);   
  22. }  
	// ********************* OGNL訪問集合元素 **************************//
public void testOgnl_20() throws Exception{
Object root = new Object();
Map context = new HashMap();
//用OGNL創建List對象
List listvalue = (List)Ognl.getValue("{123,'kdjfk','oooo'}", context, root);
context.put("listvalue", listvalue);
//用OGNL創建數組
int[] intarray= (int[])Ognl.getValue("new int[]{23,45,67}", context, root);
context.put("intarray", intarray);
//用OGNL創建Map對象
Map mapvalue = (Map)Ognl.getValue("#{'listvalue':#listvalue,'intarray':#intarray}", context, root);
context.put("mapvalue", mapvalue);
Ognl.getValue("@[email protected](#listvalue[0])", context, root);
Ognl.getValue("@[email protected](#intarray[1])", context, root);
Ognl.getValue("@[email protected](#mapvalue['intarray'][2])", context, root);
Ognl.getValue("@[email protected](#mapvalue.intarray[0])", context, root);
}

 

 

 

參考資料

學習

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