In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-04-06 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
What is the principle of OGNL expression in Struts2? I believe many inexperienced people don't know what to do about it. Therefore, this paper summarizes the causes and solutions of the problem. Through this article, I hope you can solve this problem.
1. Basic knowledge of OGNL expressions
II. OGNL and Struts2
OGNL expression
OGNL, whose full name is Object-Graph Navigation Language, is a powerful expression language used to get and set the properties of Java objects. It aims to provide a higher and more abstract level to navigate Java object graphs.
The basic unit of an OGNL expression is the navigation chain, which consists of the following parts:
Attribute name (property)
Method call (method invoke)
Array element
All OGNL expressions are evaluated based on the context of the current object, and the result of the first part of the chain is used as the context for the later evaluation. For example: names [0] .length ().
Example: the first OGNL program
Public class OGNL1 {public static void main (String [] args) {/ * create a Person object * / Person person = new Person (); person.setName ("zhangsan"); try {/ * get the value of the name attribute from the person object * / Object value = Ognl.getValue ("name", person) System.out.println (value);} 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:
Zhangsan
You can see that we have correctly obtained the value of the name attribute of the person object, and the getValue declaration is as follows:
Public static T getValue (String expression,Object root) throws OgnlException Convenience method that combines calls to parseExpression and getValue. Parameters: expression-the OGNL expression to be parsed root-the root object for the OGNL expression Returns: the result of evaluating the expression
OGNL extracts the value from the root object (root) based on the expression.
Example: using OGNL in context
Public class OGNL1 {public static void main (String [] args) {/ * create a context Context object, which is used to save multiple objects an environment object * / Map context = new HashMap (); Person person1 = new Person (); person1.setName ("zhangsan"); Person person2 = new Person (); person2.setName ("lisi") Person person3 = new Person (); person3.setName ("wangwu"); / * person4 is not placed in the context * / Person person4 = new Person (); person4.setName ("zhaoliu"); / * add person1, person2, person3 to the context (context) * / context.put ("person1", person1) Context.put ("person2", person2); context.put ("person3", person3); try {/ * get the value of the "name" attribute of the root object * / Object value = Ognl.getValue ("name", context, person2); System.out.println ("ognl expression\" name\ "evaluation is:" + value) / * get the "name" attribute value of the root object * / 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) / * specify person4 as the root object and get the "name" attribute of the person4 object. Note that the person4 object is not in the context * / Object value4 = Ognl.getValue ("name", context, person4); System.out.println ("ognl expression\" name\ "evaluation is:" + value4) / * specify person4 as the root object and get the "name" attribute of the person4 object. Note that the person4 object is not in the context * / Object value5 = Ognl.getValue ("# person4.name", context, 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 the context * / 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;}}
Console output:
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)
For OGNL that uses context, if you do not specify which object to find the "name" attribute from, OGNL looks directly from the root object (root). If you specify a lookup object (specified with the'# 'symbol, such as # person1), you will find it from the specified object. If the specified object is not in the context, an exception will be thrown. In other words, if you specify a lookup object in the form of # person1.name, you must ensure that the specified object is in the context.
Example: calling a method using OGNL
A context class provided by public class OGNL2 {public static void main (String [] args) {/ * OGNL 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 the static method * / Object min = Ognl.getValue ("@ java.lang.Math@min (4mem10)", context, context.getRoot ()); System.out.println ("min (4Magne10) is:" + min) / * call the 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 is: 4 E is: 2.718281828459045
It is also very easy to use OGNL to call a method. For member method calls, you only need to give the name of the method + (). If there are any parameters, write them directly in parentheses, which is consistent with the general call to the Java method. For static method calls, you need to use the following format: @ ClassName@method, for static variables, you need to use the following format: @ ClassName@field.
Example: use OGNL to manipulate collections
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); / * get the students collection of classroom * / Object collection = Ognl.getValue ("students", context, context.getRoot ()); System.out.println ("students collection is:" + collection) / * get the students collection of classroom * / Object firstStudent = Ognl.getValue ("students [0]", context, context.getRoot ()); System.out.println ("first student is:" + firstStudent); / * call the method of the collection * / Object size = Ognl.getValue ("students.size ()", context, context.getRoot ()) System.out.println ("students collection size is:" + size); System.out.println ("--elegant dividing 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 first element of contactWays is:" + firstElement) System.out.println ("--elegant split line--"); / * create a collection * / 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 students = new ArrayList (); public List getStudents () {return students } public void setStudents (List students) {this.students = students;}} class Student {private Map contactWays = new HashMap (); public Map getContactWays () {return contactWays;} public void setContactWays (Map contactWays) {this.contactWays = contactWays;}}
Output of the console:
Students collection is: [zhangsan, lisi, wangwu, zhaoliu, qianqi] first student is: zhangsan students collection size is: 5-- elegant dividing line-- mapCollection is: {homeNumber=110, mobilePhone=112 CompanyNumber=119} the first element of contactWays is: 110-- elegant dividing line-- [aa, bb, cc, dd] {key1=value1, key2=value2}
OGNL can not only manipulate collection objects, but also create collection objects. There is no difference between collection operations and attribute operations. It is important to note that OGNL thinks that List is the same as Array. Use {} when creating List collections using OGNL and # {} when creating Map objects.
Example: use OGNL to filter collections and projection collections
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 ("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); / * the syntax of the OGNL filter collection is: collection. {? Expression} * / Object filterCollection = Ognl.getValue ("friends. {? # this.name.length () > 7}", context, context.getRoot ()); System.out.println ("filterCollection is:" + filterCollection) The syntax of System.out.println ("--elegant split line--"); / * OGNL projection set 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 friends = new ArrayList (); 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 getFriends () {return friends;} public void setFriends (List friends) {this.friends = friends @ Override public String toString () {return "Humen [name=" + name + ", sex=" + sex + ", age=" + age + "]";}}
Console output:
FilterCollection is: [Humen [name=zhangsan, sex=n, age=22]]-- elegant dividing line-- projectionCollection is: [zhangsan, lisi, wangwu, zhaoliu, qianqi, sunba, yangqiu]
OGNL can filter and project collections. The syntax for filtering is collection. {? Expression}, where "# this" is used to represent the current object of the collection (which can be compared with the for-each loop). The syntax for projection is collection. {expression}. Projection and filtering can be seen as the operation of fetching columns and rows from the table in the database.
Struts2 and OGNL
Struts 2 supports the following expression languages:
1. OGNL (Object-Graph Navigation Language), an open source expression language that can easily manipulate object properties
2. JSTL (JSP Standard Tag Library), JSP 2.0 integrated standard expression language
3. Groovy, a dynamic language based on Java platform, has some features of popular dynamic languages such as Python, Ruby and Smarttalk.
4. Velocity, strictly speaking, is not an expression language, it is a Java-based template matching engine, it is said that its performance is better than JSP.
The default expression language for Struts 2 is OGNL because it has the following advantages over other expression languages:
1. Support object method calls, such as xxx.doSomeSpecial ()
two。 Static method calls and value access of classes are supported. The format of the expression is @ [class full name (including package path)] @ [method name | value name], for example: @ java.lang.String@format ('foo% name,' bar') or @ tutorial.MyConstant@APP_NAME
3. Support for assignment operations and concatenation of expressions, such as price=100, discount=0.8, calculatePrice (), which returns 80
4. Access OGNL context (OGNL context) and ActionContext
5. Manipulate the collection object.
-the above is quoted from http://www.blogjava.net/max/archive/2007/04/28/114417.html
Usually there are some strange problems when using Struts2 tags, and people who don't know about OGNL may be powerless to solve the problems or don't know how to solve them even if they have solved them. Here's a summary of some of the perplexities that can easily arise when using Struts2 tags:
Question 1: #,% {}, $symbol
The symbol "#" or "% {}" often appears in the Struts2 tag attribute. Through the basic introduction of the OGNL expression above, we know that there is one and only one root object in the OGNL context. Struts2 defines many explicit objects for us, which are "ValueStack", "Parameters", "Session", "Request", "Appliction", "Attr", where "ValueStack" is set as the root object of the context. Access to non-root objects must be marked with a "#", which is why "#" appears. Not all of the target processing classes in Struts2 treat the attributes of the tag as OGNL expressions, and sometimes we need to set dynamic values, then we must tell the processing class of the tag that the string is handled according to the OGNL expression, and the function of the% {} symbol is to tell the processing class of the tag to process the string it contains according to the OGNL expression. The "$" symbol is used in XML files to get dynamic values, similar to% {}.
Question 2: the influence of% {} symbols
There are hundreds of tags in Struts2. It is difficult to remember which tag processing class treats the attributes of the tag as OGNL expressions. What to do when it is not clear how to handle the class?% {} for the tag processing class, if the processing class treats the attribute value as an ordinary string, the string contained in the% {} symbol is treated as an OGNL expression, and if the processing class treats the attribute value as an OGNL expression The% {} symbol is ignored directly. In other words, if you don't know how to handle it, you can all use the% {} symbol.
Question 3: how do tags get data?
Here is the official description of 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).
General meaning: ValueStack allows you to save multiple bean (that is, Action) and get them using the expression language. When evaluating an expression, ValueStack will be searched from the top of the stack to the bottom of the stack, looking for the getter or setter method of bean for a given property name or looking for a given method.
Whenever a request arrives at Action, Struts2 pushes the Action object into the ValueStack.
Username:-weird dividing line-username:
The page displays the results:
Username:zhangsan-weird dividing line-username:zhangsan
You can see that the value of the tag is the same as that of using the Java code, and it is obvious that the value of the tag is more concise and concise. The OGNL expression "username" represents the value of the property username taken from the root object ValueStack. It traverses the ValueStack from the top of the stack to the bottom of the stack until it finds the "username" attribute in an Action.
After reading the above, have you mastered the principle of OGNL expression in Struts2? If you want to learn more skills or want to know more about it, you are welcome to follow the industry information channel, thank you for reading!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 282
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.