OGNL使用详解一:原理与常用语法方式
2014-05-11 23:36
85 查看
OGNL使用详解一:原理与常用语法方式
OGNL:Object-Graph Navigation Language,一种功能强大的表达式语言(Expression Language,简称为EL),通过它简单一致的表达式语法,可以存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化等功能。它使用相同的表达式去存取对象的属性。
以上关于OGNL的定义是在百度百科中的描述,其实通俗的讲,就是ognl的context对象解析一个ognl字符串,返回相应的结果。
简单讲一下OGNL的几个重要的概念:
1.OgnlContext:它实现了Map接口,以key-value键值对形式存在,不同于普通map的是,里面存在唯一的叫做根的对象(root),可以通过程序设定上下文中哪个对象是根对象。
2.root对象:root对象与普通对象都是OgnlContext中的元素,但是OgnlContext默认取根对象,如果是非根对象,需要在ognl表达式前加"#"。
3.OgnlContext里面默认就放了四个对象:request,application,session,parameters。
4.OgnlContext的根对象在初始化时是空的
这里需要提一句,OGNL本身和Struts2没有任何关系,经常听到有人说OGNL是Struts2的,对此很无语。仅仅是Struts2支持OGNL,并且在此基础上增加了一些东西。
由于语法过于复杂,以下用一个demo项目来做演示:
第一步:新建一个Java Project
第二步:引入两个ognl需要的jar:ognl.3.0.6.jar,javassist-3.11.0.jar包。
第三步:加入两个bean:
第四步:编写OGNL语法测试类:
OGNL:Object-Graph Navigation Language,一种功能强大的表达式语言(Expression Language,简称为EL),通过它简单一致的表达式语法,可以存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化等功能。它使用相同的表达式去存取对象的属性。
以上关于OGNL的定义是在百度百科中的描述,其实通俗的讲,就是ognl的context对象解析一个ognl字符串,返回相应的结果。
简单讲一下OGNL的几个重要的概念:
1.OgnlContext:它实现了Map接口,以key-value键值对形式存在,不同于普通map的是,里面存在唯一的叫做根的对象(root),可以通过程序设定上下文中哪个对象是根对象。
2.root对象:root对象与普通对象都是OgnlContext中的元素,但是OgnlContext默认取根对象,如果是非根对象,需要在ognl表达式前加"#"。
3.OgnlContext里面默认就放了四个对象:request,application,session,parameters。
4.OgnlContext的根对象在初始化时是空的
这里需要提一句,OGNL本身和Struts2没有任何关系,经常听到有人说OGNL是Struts2的,对此很无语。仅仅是Struts2支持OGNL,并且在此基础上增加了一些东西。
由于语法过于复杂,以下用一个demo项目来做演示:
第一步:新建一个Java Project
第二步:引入两个ognl需要的jar:ognl.3.0.6.jar,javassist-3.11.0.jar包。
第三步:加入两个bean:
package ognl.bean; /** * * @author wangjian * */ public class Dog { private String name; private String[] friends; public String[] getFriends() { return friends; } public void setFriends(String[] friends) { this.friends = friends; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
package ognl.bean; /** * * @author wangjian * */ public class Person { private String name; private Dog dog; public Person() { super(); } public Person(String name) { this.name = name; } public Dog getDog() { return dog; } public void setDog(Dog dog) { this.dog = dog; } public String getName() { System.out.println("getName invoked!"); return name; } public void setName(String name) { this.name = name; } }
第四步:编写OGNL语法测试类:
package ognl; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import ognl.bean.Dog; import ognl.bean.Person; /** * * @author wangjian * */ public class OGNLTest { public static void main(String[] args) throws OgnlException { Person person = new Person(); person.setName("Steven"); Dog dog2 = new Dog(); dog2.setName("hello world"); person.setDog(dog2); Dog dog = new Dog(); dog.setName("hello world your sister"); OgnlContext context = new OgnlContext(); // 把对象以键值对形式放进去 context.put("person", person); context.put("dog", dog); // 设定这个OGNL的根root是person对象 context.setRoot(person); // 解析一个表达式(取跟对象的属性的时候,无需加#,直接写属性名字,默认从根对象中取属性) Object object = Ognl.parseExpression("name"); System.out.println(object); Object object2 = Ognl.getValue(object, context, context.getRoot()); System.out.println(object2); System.out.println("----------------------------"); // #表示取的不是根对象,表示取context里面存的person对象里面的name属性 Object object3 = Ognl.parseExpression("#person.name"); System.out.println(object3); Object object4 = Ognl.getValue(object3, context, context.getRoot()); System.out.println(object4); System.out.println("----------------------------"); // #表示取的不是根对象,表示取context里面存的dog对象里面的name属性 Object object5 = Ognl.parseExpression("#dog.name"); System.out.println(object5); Object object6 = Ognl.getValue(object5, context, context.getRoot()); System.out.println(object6); System.out.println("----------------------------"); // 属性后买年可以直接调String的方法 Object object7 = Ognl.parseExpression("name.toUpperCase().length()"); System.out.println(object7); Object object8 = Ognl.getValue(object7, context, context.getRoot()); System.out.println(object8); System.out.println("----------------------------"); // 调用ONGL的静态方法时用两个@@符号:@表示类名@表示方法名 Object object9 = Ognl.parseExpression("@java.lang.Integer@toBinaryString(10)"); System.out.println(object9); Object object10 = Ognl.getValue(object9, context, context.getRoot()); System.out.println(object10); System.out.println("----------------------------"); // 调用ONGL的静态方法时用两个@@符号:不写类名,默认是java.lang.Math类,@@直接写Math类里面的方法 Object object11 = Ognl.parseExpression("@@min(4, 10)"); System.out.println(object11); Object object12 = Ognl.getValue(object11, context, context.getRoot()); System.out.println(object12); System.out.println("----------------------------"); // new一个LinkedList Object object13 = Ognl.parseExpression("new java.util.LinkedList()"); System.out.println(object13); Object object14 = Ognl.getValue(object13, context, context.getRoot()); System.out.println(object14); System.out.println("----------------------------"); // 一个字符串集合(外面用双引号了,里面就用单引号), Object object15 = Ognl.getValue("{'aa', 'bb', 'cc', 'dd'}", context,context.getRoot()); System.out.println(object15); System.out.println("----------------------------"); // 一个字符串集合(OGNL中,集合与数组是等同的),取第三个元素 Object object16 = Ognl.getValue("{'aa', 'bb', 'cc', 'dd'}[2]", context,context.getRoot()); System.out.println(object15); System.out.println("----------------------------"); dog.setFriends(new String[] { "aa", "bb", "cc" }); // dog对象的friends数组 Object object17 = Ognl.getValue("#dog.friends", context,context.getRoot()); System.out.println(object17); System.out.println("----------------------------"); dog.setFriends(new String[] { "aa", "bb", "cc" }); // dog对象的friends数组的第二个元素 Object object18 = Ognl.getValue("#dog.friends[1]", context,context.getRoot()); System.out.println(object18); List<String> list = new ArrayList<String>(Arrays.asList("hello","world", "hello world")); context.put("list", list); System.out.println(Ognl.getValue("#list", context, context.getRoot())); System.out.println(Ognl.getValue("#list[1]", context, context.getRoot())); System.out.println("----------------------------"); // OGNL的映射(Map):#{}表示这是一个映射Map,这里的#与取非根元素的#不同,仅仅表示这是一个映射Map而已 System.out.println(Ognl.getValue("#{'key1': 'value1', 'key2': 'value2', 'key3': 'value3', 'key4': 'value4'}",context, context.getRoot())); // OGNL返回映射中某key对应的value System.out.println(Ognl.getValue("#{'key1': 'value1', 'key2': 'value2', 'key3': 'value3', 'key4': 'value4'}['key3']",context, context.getRoot())); System.out.println("----------------------------"); List<Person> persons = new ArrayList<Person>(Arrays.asList(new Person("doctor"), new Person("worker"), new Person("student"))); context.put("persons", persons); // 过滤:collection.{?开头 // expression},对一个集合进行过滤,返回过滤后结果(OGNL提供了伪属性,"#persons.{? #this.name.length() > 4}.size"也可以) System.out.println(Ognl.getValue("#persons.{? #this.name.length() > 4}", context,context.getRoot())); System.out.println(Ognl.getValue("#persons.{? #this.name.length() > 4}.size()", context,context.getRoot())); System.out.println(Ognl.getValue("#persons.{? #this.name.length() > 4}[0].name", context,context.getRoot())); // 过滤(filtering),获取到过滤后的集合中的第一个元素^, collection.{^ expression} System.out.println(Ognl.getValue("#persons.{^ #this.name.length() > 4}", context,context.getRoot())); // 过滤(filtering),获取到过滤后的集合中的第一个元素$, collection.{$ expression} System.out.println(Ognl.getValue("#persons.{$ #this.name.length() > 4}", context,context.getRoot())); System.out.println("----------------------------"); // 投影(projection), collection. {expression} System.out.println(Ognl.getValue("#persons.{name}", context,context.getRoot())); System.out.println("----------------------------"); System.out.println(Ognl.getValue("#persons.{#this.name.length() <= 5 ? 'Hello World' : #this.name}",context, context.getRoot())); } }
相关文章推荐
- GitHub的使用原理与常用命令详解(一)
- Android RxJava第一弹之原理详解、使用详解、常用场景(基于Rxjava2.0)
- JAVAWEB开发之权限管理(一)——权限管理详解(权限管理原理以及方案)、不使用权限框架的原始授权方式详解
- JAVAWEB开发之SpringMVC详解(一)——SpringMVC的框架原理、架构简介、与mybatis整合和注解方式的使用、
- JAVAWEB开发之SpringMVC详解(一)——SpringMVC的框架原理、架构简介、与mybatis整合和注解方式的使用、
- ptrace运行原理及使用详解
- 【 Makefile 编程基础之四】详解Makefile 函数的语法与使用(下)
- LINUX中的周期性进程cron原理及使用详解
- RxAndroid的使用方式6-Retrofit2.0使用详解
- Memcached常用命令以及使用说明详解
- SYNOPSYS VCS常用命令使用详解
- Android中View(视图)绘制不同状态背景图片原理深入分析以及StateListDrawable使用详解
- Struts2学习(第十篇)——ognl概念和原理详解
- 走进AngularJs(二) ng模板中常用指令的使用方式
- VC常用数据类型使用转换详解
- daemon函数的原理及使用详解
- VC常用数据类型使用转换详解
- VC常用数据类型使用转换详解
- Android动画使用方式详解
- 基于JavaScript实现继承机制之构造函数+原型链混合方式的使用详解