Using an example to learn more about OGNL expressions in the Struts framework of Java _java

Source: Internet
Author: User
Tags access properties

Struts 2 The default expression language is OGNL, because it has the following advantages over other expression languages:
1. Support Object method invocation, such as xxx.dosomespecial ();
2. Support class static method invocation and value access, expression format is @[class full name (including package path)]@[Method name | Value name], for example: @java. Lang.string@format (' foo%s ', ' Bar ') or @tutorial. Myconstant@app_name;
3. Support assignment operation and expression concatenation, such as price=100, discount=0.8, Calculateprice (), this expression will return 80;
4. Access to OGNL contexts (OGNL context) and actioncontext;
5. Manipulate collection objects.
Let's look at a few examples of OGNL use:

Example: Using OGNL in a context environment

public class OGNL1 {public static void main (string[] args) {/* Creates a context object, which is an environment object that holds multiple objects/Ma 
 
    P<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 not put into context/person person4 = new person (); 
 
    Person4.setname ("Zhaoliu"); 
    /* Add Person1, Person2, Person3 to the environment (in context)/Context.put ("Person1", Person1); 
    Context.put ("Person2", Person2); 
 
    Context.put ("Person3", Person3); 
      try {* * Gets the root object's "name" property value of */Object value = Ognl.getvalue ("name", context, Person2); 
 
      System.out.println ("OGNL expression \" name\ "Evaluation is:" + value); 
      /* Get the root object's "name" attribute value/Object value2 = Ognl.getvalue ("#person2. Name", context, Person2); System.out.println ("Ognl EXpression \ "#person2. Name\" Evaluation is: "+ value2); 
      /* Get the "name" attribute value of the Person1 object/Object value3 = Ognl.getvalue ("#person1. Name", context, Person2); 
 
      System.out.println ("OGNL expression \" #person1. Name\ "Evaluation is:" + value3); /* Specifies the Person4 as the root object, gets the "name" attribute of the Person4 object, and notices that the Person4 object is not in context * * Value4 = ognl.getvalue ("name", Contexts, Perso 
      N4); 
 
      System.out.println ("OGNL expression \" name\ "Evaluation is:" + value4); /* Specifies the Person4 as the root object, gets the "name" attribute of the Person4 object, and notices that the Person4 object is not in context * * Value5 = Ognl.getvalue ("#person4. Name", Conte 
      XT, Person4); 
 
      System.out.println ("OGNL expression \" person4.name\ "Evaluation is:" + value5); 
      /* Get the "name" attribute of the Person4 object, note that the Person4 object is not in context///Object value6 = Ognl.getvalue ("#person4. Name", contexts, 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; 
 } 
}

Console output:

OGNL expression "name" evaluation Is:lisi 
OGNL expression "#person2. Name Evaluation Is:lisi 
#person1. Name "Evaluation Is:zhangsan 
OGNL expression" name "Evaluation Is:zhaoliu 
. 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) 

For OGNL that use the context, if you do not specify which object to look up the "name" attribute from, the OGNL is found directly from the root object (root), and if you specify a Lookup object (using the ' # ' number, such as #person1), look for the specified object. If the specified object is not in the context, an exception is thrown, in other words, the #person1.name form specifies that the lookup object must ensure that the specified object is in the context.

Example: calling methods using OGNL

The public class OGNL2 {public static void main (string[] args) {/* OGNL provides a context class that implements the map interface */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 {* * Call member method/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); 
      /* Call static method */Object min = Ognl.getvalue ("@java. Lang.math@min (4,10)", Context, context.getroot ()); 
 
      System.out.println ("min (4,10) is:" + min); 
      /* Call static variable */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; 
 } 
}

Console output:

People1 name length is:8 
people2 name uppercase Is:lisi people1 Name.charat 
(5) is:s 
min (4,10) is:4 
E I s:2.718281828459045 

Using the OGNL call method is also very simple, for member method calls, just give the name of the Method + (), if there are parameters, write directly in parentheses, consistent with the general invoke Java method. For calls to static methods, you need to use the following format: @ClassName @method, you need to use the following format for static variables: @ClassName @field.

Example: Using the OGNL action collection

public class OGNL3 {public static void main (string[] args) throws Exception {Ognlcontext context = new OGNL 
     
    Context (); 
    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); 
    /* Get classroom Students set/Object collection = Ognl.getvalue ("Students", Context, context.getroot ()); 
 
    SYSTEM.OUT.PRINTLN ("Students Collection is:" + collection); /* Get Classroom students set */Object firststudent = Ognl.getvalue ("sTudents[0] ", Context, context.getroot ()); 
 
    System.out.println ("The Student is:" + firststudent); 
    /* method to call the collection * * Object size = Ognl.getvalue ("Students.size ()", Context, context.getroot ()); 
 
    SYSTEM.OUT.PRINTLN ("Students Collection size is:" + size); 
     
    System.out.println ("--------------------------Elegant split Line--------------------------"); 
    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" the "The Contactways is:" + firstelement); 
 
    System.out.println ("--------------------------Elegant split Line--------------------------"); 
    /* Create set/Object CreateCollection = Ognl.getvalue ("{' AA ', ' BB ', ' cc ', ' DD '}", Context, context.getroot ()); 
 
    System.out.println (createcollection); /* Create Map Collection */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; 
 } 
}

Output of the console:

Students collection is: [Zhangsan, Lisi, Wangwu, Zhaoliu, Qianqi], A/student Is:zhangsan students 
Size Is:5 
--------------------------Elegant split line-------------------------- 
Mapcollection is: {homenumber=110, mobilephone=112, companynumber=119} The ' the ' the ' the ' of 
contactways is:110 
-------------------------- Elegant Split line-------------------------- 
[AA, BB, CC, DD] 
{key1=value1, key2=value2} 

OGNL can not only manipulate the collection object, but also create collection objects, the collection operation and the operation of the property is not different, it is necessary to note that the list and array are the same OGNL. Use {} When creating a list collection using OGNL, use #{} when creating a Map object.

Example: Using OGNL to filter collections and projection collections

public class OGNL4 {public static void main (string[] args) throws Exception {Ognlcontext context = new OGNL 
 
    Context (); 
    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 The syntax of the filter set is: Collection. {expression} */Object filtercollection = Ognl.getvalue ("friends.{? 
    #this. Name.length () > 7} ", Context, context.getroot ()); 
 
    System.out.println ("Filtercollection is:" + filtercollection); System.out.println ("--------------------------Flowing split Line--------------------------"); /* The syntax for the OGNL projection collection is: 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 

Console output:

Filtercollection is: [Humen [Name=zhangsan, Sex=n, age=22]] 
-------------------------- Elegant Split Line-------------------------- 
projectioncollection is: [Zhangsan, Lisi, Wangwu, Zhaoliu, Qianqi, Sunba, Yangqiu ] 

OGNL can filter and project the set, and the syntax of filtering is collection. {? expression}, which uses "#this" to represent the current object of the collection (which can be compared to for-each loops). The syntax for the projection is collection. {expression}. Projection and filtering can be seen as the operation of table fetching and fetching rows in a database.

Some common problems
usually use Struts2 label will appear some very strange problems, for OGNL not understand people may be powerless or even solve the problem is not know how to solve. Here's a summary of some of the puzzles that are easy to use with Struts2 tags:

Question one: #,%{},$ symbol

Symbol occurrences of "#" or "%{}" often appear in the STRUTS2 tag properties, which are described in the OGNL expression basis above, knowing that there is only one root object in the OGNL context. Struts2 for us to define a lot of obvious objects, they are "valuestack", "Parameters", "Session", "Request", "appliction", "Attr", where "Valuestack" is set to the root object of the context. Access to a non-root object must be preceded by a "#" number, which is why "#" appears. In the Struts2 of the standard processing class, not all of the label's properties as a OGNL expression to treat, sometimes we need to set the dynamic value, you have to tell the label's processing class that string is processed in OGNL expression,%{} The function of a symbol is to tell the label's processing class to handle the string it contains according to the OGNL expression. The "$" symbol is used in the XML file to get the dynamic value similar to the%{} function.

Question two: The influence of%{} symbols

STRUTS2 's label a few Baisi, it is difficult to remember which tag's processing class will label attributes as OGNL expressions, and what to do when dealing with a class,%{} for a label processing class, if the class takes the property value as a normal string%{} The symbol contains a string as a OGNL expression, and if the processing class treats the property value as a OGNL expression, the%{} symbol is ignored directly. In other words, you can use the%{} symbol if you don't know how to handle it.

Question three: How the label gets the data

The following is the official description of Valuestack:

Valuestack allows multiple beans to is pushed in and dynamic EL expressions to be evaluated against it. When evaluating an expression, the stack is searched down the stack, from the latest objects pushed into to the earlies T, looking for a beans with a-getter or setter for the "given" or "a" of the given name (depending on the Expre Ssion being evaluated).

General meaning: Valuestack allows multiple beans (that is, action) to be saved, and they can be obtained using an expression language. When evaluating an expression, valuestack will be searched from the top of the stack to the bottom of the stack, looking for a bean's getter or setter method for a given property name or for a given method.

Whenever a request arrives at the action, Struts2 pushes the action object into the Valuestack.

<body>  
  username:<s:property value= "username"/><br/> 
  ------------------- The bizarre split line-------------------<br/> 
  username:<%= (helloworldaction) Actioncontext.getcontext (). Getvaluestack (). Peek ()). GetUserName ()%><br/> 
 </body> 

Page Display results:

Username:zhangsan 
-------------------Weird split line------------------- 
Username:zhangsan 

You can see that the label value is the same as the result of using Java code, and the value of the marked tag is more concise. The OGNL expression "username" represents a value that removes a property username from the root object valuestack. It traverses valuestack from the top of the stack to the bottom of the stack until you find the "username" attribute in an action.


Summary of the use of OGNL:

1. Access Properties
Name property gets:

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

Address Properties Get:

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

2. Access Methods
common method for calling objects in the value stack:

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

3. Accessing static properties and methods
call the static method in action:

<s:property value= "@struts. Action.loginaction@get ()"/>

To invoke a static method of a class in the JDK:

<s:property value= "@java. Lang.math@floor (44.56)"/><br>

static method to invoke class in JDK (IBID.):

 <s:property value= "@ @floor (44.56)"/><br>

To invoke a static method of a class in the JDK:

<s:property value= "@java. Util.calendar@getinstance ()"/><br>

To invoke a static property in a normal class:

<s:property value= "@struts. Vo.address@tips"/><br>

Accessing construction methods
To invoke the construction method of a normal class:

<s:property value= "New Struts.vo.Student" (' Li Xiaohong ', ' Belle ', 3,). Username "/>

4. Accessing arrays
Get list:

<s:property value= "Testlist"/><br>

Gets an element in the list (you can get the contents of the list using a subscript similar to an array):

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

Get set:

<s:property value= "Testset"/><br>

Gets one of the elements in the set (set cannot get data using subscript because there is no order):

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

Get map:

<s:property value= "TestMap"/><br>

Get all the keys in the map:

<s:property value= "Testmap.keys"/><br>

Get all the values in the map:

<s:property value= "Testmap.values"/><br>

Gets an element in the map (you can get the contents of the list using a subscript similar to an array):

<s:property value= "testmap[' M1 ']"/><br>

Get the size of the list:

<s:property value= "Testset.size"/><br>

5. Access Collection – Projection, selection (? ^ $)
take advantage of the choice to obtain a pass in the list of the object: <s:property value= "Stus. {#this. grade>=60} "/><br>

Take advantage of the choice to get the username of the list of successful objects:

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

Use the selection to get the username of the first object in the list:

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

Use the selection to get the username of the first object in the list:

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

Use the selection to get the username of the last object in the list:

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

Use the selection to get the first object in the list and then size:

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

Pseudo property of collection
OGNL can refer to some of the special properties of the collection, which are not javabeans modes such as size (), length (), and so on. When an expression references these properties, OGNL invokes the appropriate method, which is the pseudo attribute.

6.LAMBDA: [...]
format:: [...]
To calculate a factorial using a lambda expression:

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

The use of # 7.OGNL
#可以取出堆栈上下文中的存放的对象.

Gets the properties of the Paraments object: <s:property value= "#parameters. Username"/>

Use of the% 8.OGNL
you can use%{} to remove the action object in the existing value stack and call its method directly.

For example, if your action inherits Actionsupport. Then in the page label, use the%{gettext (' key ')} in the way you can get the internationalization information.

The use of $9.OGNL

"$" has two main uses

    1. Used to reference OGNL expressions in an internationalized resource file
    2. In the Struts 2 configuration file, refer to the OGNL expression

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.