程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 經由過程實例深刻進修Java的Struts框架中的OGNL表達式應用

經由過程實例深刻進修Java的Struts框架中的OGNL表達式應用

編輯:關於JAVA

經由過程實例深刻進修Java的Struts框架中的OGNL表達式應用。本站提示廣大學習愛好者:(經由過程實例深刻進修Java的Struts框架中的OGNL表達式應用)文章只能為提供參考,不一定能成為您想要的結果。以下是經由過程實例深刻進修Java的Struts框架中的OGNL表達式應用正文


Struts 2默許的表達式說話是OGNL,緣由是它絕對其它表達式說話具有上面幾年夜優勢:
1. 支撐對象辦法挪用,如xxx.doSomeSpecial();
2. 支撐類靜態的辦法挪用和值拜訪,表達式的格局為@[類全名(包含包途徑)]@[辦法名 | 值名],例如:@java.lang.String@format('foo %s', 'bar')或@tutorial.MyConstant@APP_NAME;
3. 支撐賦值操作和表達式串連,如price=100, discount=0.8, calculatePrice(),這個表達式會前往80;
4. 拜訪OGNL高低文(OGNL context)和ActionContext;
5. 操作聚集對象。
上面我們來看OGNL應用的幾個例子:

示例:高低文情況中應用OGNL

public class OGNL1 
{ 
  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"); 
 
    /* 將person1、person2、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); 
 
    } 
    catch (OgnlException e) 
    { 
      e.printStackTrace(); 
    } 
  } 
} 
 
class Person 
{ 
  private String name; 
 
  public String getName() 
  { 
    return name; 
  } 
 
  public void setName(String name) 
  { 
    this.name = name; 
  } 
} 

掌握台輸入:

ognl expression "name" evaluation is : lisi 
ognl expression "#person2.name" evaluation is : lisi 
ognl expression "#person1.name" evaluation is : zhangsan 
ognl expression "name" evaluation is : zhaoliu 
ognl.OgnlException: source is null for getProperty(null, "name") 
  at ognl.OgnlRuntime.getProperty(OgnlRuntime.java:2296) 
  at ognl.ASTProperty.getValueBody(ASTProperty.java:114) 
  at ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:212) 
  at ognl.SimpleNode.getValue(SimpleNode.java:258) 
  at ognl.ASTChain.getValueBody(ASTChain.java:141) 
  at ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:212) 
  at ognl.SimpleNode.getValue(SimpleNode.java:258) 
  at ognl.Ognl.getValue(Ognl.java:494) 
  at ognl.Ognl.getValue(Ognl.java:596) 
  at ognl.Ognl.getValue(Ognl.java:566) 
  at com.beliefbetrayal.ognl.OGNL1.main(OGNL1.java:53) 

關於應用高低文的OGNL,若不指定從哪個對象中查找"name"屬性,則OGNL直接從根對象(root)查找,若指定查找對象(應用'#'號指定,如#person1),則從指定的對象中查找,若指定對象不在高低文中則會拋出異常,換句話說就是是#person1.name情勢指定查找對象則必需要包管指定對象在高低文情況中。

示例:應用OGNL挪用辦法

public class OGNL2 
{ 
  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); 
    } 
    catch (OgnlException e) 
    { 
      e.printStackTrace(); 
    } 
  } 
} 
 
class People 
{ 
  private String name; 
 
  public String getName() 
  { 
    return name; 
  } 
 
  public void setName(String name) 
  { 
    this.name = name; 
  } 
} 

掌握台輸入:

people1 name length is :8 
people2 name upperCase is :LISI 
people1 name.charAt(5) is :s 
min(4,10) is :4 
E is :2.718281828459045 

應用OGNL挪用辦法也非常簡略,關於成員辦法挪用,只須要給出辦法的稱號+(),如有參數,直接寫在括號內,與普通挪用Java辦法分歧。關於靜態辦法的挪用,須要應用以下格局:@ClassName@method,關於靜態變量須要應用以下格局:@ClassName@field。

示例:應用OGNL操作聚集

public class OGNL3 
{ 
  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); 
 
  } 
} 
 
class Classroom 
{ 
  private List<String> students = new ArrayList<String>(); 
 
  public List<String> getStudents() 
  { 
    return students; 
  } 
 
  public void setStudents(List<String> students) 
  { 
    this.students = students; 
  } 
} 
 
class Student 
{ 
  private Map<String , Object> contactWays = new HashMap<String , Object>(); 
 
  public Map<String , Object> getContactWays() 
  { 
    return contactWays; 
  } 
 
  public void setContactWays(Map<String , Object> contactWays) 
  { 
    this.contactWays = contactWays; 
  } 
} 

掌握台的輸入:

students collection is :[zhangsan, lisi, wangwu, zhaoliu, qianqi] 
first student is : zhangsan 
students collection size is :5 
--------------------------潇灑的朋分線-------------------------- 
mapCollection is :{homeNumber=110, mobilePhone=112, companyNumber=119} 
the first element of contactWays is :110 
--------------------------潇灑的朋分線-------------------------- 
[aa, bb, cc, dd] 
{key1=value1, key2=value2} 

OGNL不只可以操作聚集對象,還可以創立聚集對象,對聚集操作與對屬性的操作沒甚麼分歧,須要留意的是OGNL以為List與Array是一樣的。應用OGNL創立List聚集時應用{},創立Map對象時應用#{}。

示例:應用OGNL過濾聚集與投影聚集

public class OGNL4 
{ 
  public static void main(String[] args) throws Exception 
  { 
    OgnlContext context = new OgnlContext(); 
 
    Humen humen = new Humen(); 
    humen.setName("qiuyi"); 
    humen.setSex("n"); 
    humen.setAge(22); 
    humen.getFriends().add(new Humen("zhangsan" , "n" , 22)); 
    humen.getFriends().add(new Humen("lisi" , "f" , 21)); 
    humen.getFriends().add(new Humen("wangwu" , "n" , 23)); 
    humen.getFriends().add(new Humen("zhaoliu" , "n" , 22)); 
    humen.getFriends().add(new Humen("qianqi" , "n" , 22)); 
    humen.getFriends().add(new Humen("sunba" , "f" , 20)); 
    humen.getFriends().add(new Humen("yangqiu" , "f" , 25)); 
     
    context.put("humen", humen); 
    context.setRoot(humen); 
 
    /* OGNL過濾聚集的語法為:collection.{? expression} */ 
    Object filterCollection = Ognl.getValue("friends.{? #this.name.length() > 7}", context, context.getRoot()); 
    System.out.println("filterCollection is :" + filterCollection); 
 
    System.out.println("--------------------------潇灑的朋分線--------------------------"); 
 
    /* OGNL投影聚集的語法為:collection.{expression} */ 
    Object projectionCollection = Ognl.getValue("friends.{name}", context, context.getRoot()); 
    System.out.println("projectionCollection is :" + projectionCollection); 
  } 
} 
 
class Humen 
{ 
  private String name; 
  private String sex; 
  private int age; 
  private List<Humen> friends = new ArrayList<Humen>(); 
 
  public Humen() 
  { 
 
  } 
 
  public Humen(String name , String sex , int age) 
  { 
    this.name = name; 
    this.sex = sex; 
    this.age = age; 
  } 
 
  public String getName() 
  { 
    return name; 
  } 
 
  public void setName(String name) 
  { 
    this.name = name; 
  } 
 
  public String getSex() 
  { 
    return sex; 
  } 
 
  public void setSex(String sex) 
  { 
    this.sex = sex; 
  } 
 
  public int getAge() 
  { 
    return age; 
  } 
 
  public void setAge(int age) 
  { 
    this.age = age; 
  } 
 
  public List<Humen> getFriends() 
  { 
    return friends; 
  } 
 
  public void setFriends(List<Humen> friends) 
  { 
    this.friends = friends; 
  } 
 
  @Override 
  public String toString() 
  { 
    return "Humen [name=" + name + ", sex=" + sex + ", age=" + age + "]"; 
  } 
} 

掌握台輸入:

filterCollection is :[Humen [name=zhangsan, sex=n, age=22]] 
--------------------------潇灑的朋分線-------------------------- 
projectionCollection is :[zhangsan, lisi, wangwu, zhaoliu, qianqi, sunba, yangqiu] 

OGNL可以對聚集停止過濾與投影操作,過濾的語法為collection.{? expression},個中應用"#this"表現聚集以後對象(可以與for-each輪回比擬)。投影的語法為collection.{expression}。投影和過濾可以看作是數據庫中對表取列和取行的操作。

一些罕見成績
日常平凡應用Struts2標簽時會湧現一些很獨特的成績,關於OGNL不懂得的人能夠對成績的湧現力所不及或許就算處理了成績也不曉得是若何處理的。上面總結一些應用Struts2標簽輕易湧現的迷惑:

成績一:#,%{},$符號

在Struts2標簽屬性中常常會湧現"#"或許"%{}"的符號湧現,經由過程下面OGNL表達式基本的引見,曉得了OGNL高低文中有且唯一一個根對象。Struts2為我們界說了很多明明對象,他們分離是"ValueStack","Parameters","Session","Request", "Appliction","Attr",個中"ValueStack"被設置為高低文的根對象。拜訪非根對象必需加上"#"號,這就是湧現"#"的緣由。Struts2中的標的處置類,其實不是一切都將標簽的屬性作為OGNL表達式來對待,有時刻我們須要設置靜態地值,則必需告知標簽的處置類該字符串依照OGNL表達式來處置,%{}符號的感化就是告知標簽的處置類將它包括的字符串依照OGNL表達式處置。 "$"符號用於XML文件頂用於獲得靜態值,與%{}感化相似。

成績二:%{}符號的影響

Struts2的標簽幾十幾百個,要記住哪個標簽的處置類將標簽的屬性作為OGNL表達式是一件很艱苦的工作,在不清晰處置類的處置方法時怎樣辦,%{}關於標簽處置類來講,若處置類將屬性值作為通俗字符串則%{}符號包括的字符串當作OGNL表達式,若處置類將屬性值作為OGNL表達式來處置,則直接疏忽%{}符號。換句話說,不清晰處置方法的話,可以都應用%{}符號。

成績三:標簽是若何取得數據

上面是ValueStack的官方描寫:

ValueStack allows multiple beans to be pushed in and dynamic EL expressions to be evaluated against it. When evaluating an expression, the stack will be searched down the stack, from the latest objects pushed in to the earliest, looking for a bean with a getter or setter for the given property or a method of the given name (depending on the expression being evaluated).

年夜請安思:ValueStack許可保留多個bean(也就是Action),而且可使用表達式說話取得他們。當評價一個表達式,ValueStack將會從棧頂到棧底的偏向被搜刮一遍,關於給定的屬性稱號尋覓bean的getter或setter辦法或尋覓給定的辦法。

每當一個要求達到Action時,Struts2會將Action對象推入ValueStack中。

<body>  
  username:<s:property value="username"/><br /> 
  -------------------詭異的朋分線-------------------<br /> 
  username:<%= ((HelloWorldAction)ActionContext.getContext().getValueStack().peek()).getUsername() %><br /> 
 </body> 

頁面顯示成果:

username:zhangsan 
-------------------詭異的朋分線------------------- 
username:zhangsan 

可以看到標簽取值與用Java代碼取值的成果雷同,顯著標簽的取值方法更簡潔簡練。OGNL表達式"username"表現了從根對象ValueStack中掏出屬性username的值。它會從棧頂到棧底遍歷ValueStack,直到找某一個Action中的"username"屬性。


總結OGNL的應用辦法:

1.拜訪屬性
名字屬性獲得:

<s:property value="user.username"/><br>

地址屬性獲得:

<s:property value="user.address.addr"/><br>

2.拜訪辦法
挪用值棧中對象的通俗辦法:

<s:property value="user.get()"/><br>

3.拜訪靜態屬性和辦法
挪用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"/>

 

4.拜訪數組
獲得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>

 

5.拜訪聚集 – 投影、選擇(? ^ $)
應用選擇獲得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可以或許援用聚集的一些特別的屬性,這些屬性其實不是JavaBeans形式,例如size(),length()等等. 當表達式援用這些屬性時,OGNL會挪用響應的辦法,這就是偽屬性.

6.Lambda   :[…]
格局::[…]
應用Lambda表達式盤算階乘:

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

7.OGNL中#的應用
#可以掏出客棧高低文中的寄存的對象.

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

8.OGNL中%的應用
用%{}可以掏出存在值客棧中的Action對象,直接挪用它的辦法.

例如你的Action假如繼續了ActionSupport .那末在頁面標簽中,用%{getText('key')}的方法可以拿出國際化信息.

9.OGNL中$的應用

“$”有兩個重要的用處

  1. 用於在國際化資本文件中,援用OGNL表達式
  2. 在Struts 2設置裝備擺設文件中,援用OGNL表達式
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved