您的位置:首页 > 其它

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:

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()));

}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: