OGNL解析

Ognl简介及基本使用

OGNL(Object Graph Navigation Language)对象导航语言。

OGNL是基于java实现,本身与Strut没有任何关系,只是Struts2的API对其进行解析。

Ognl当中有OgnlConext(Ogn上下文),该类实现了java.util.Map。

Ognl当中存在唯一的一个Root(根)的对象,root对象可以通过程序自己设定上下文中的哪个对象作为根对象。

使用OGNL需要2个jar,ognl.jar和javassist.jar.

public static void main(String[] args) throws Exception {
		
		Person person = new Person();
		person.setName("张三");
		
		Dog dog = new Dog();
		dog.setName("旺财");
		
		OgnlContext ognlContext = new OgnlContext();//ognl上下文对象
		
		ognlContext.put("person", person);
		ognlContext.put("dog", dog);
		
		ognlContext.setRoot(person);//将person设置为ognl的根对象
		
		Object object1 = Ognl.parseExpression("name");
		Object object2 = Ognl.getValue(object1, ognlContext,ognlContext.getRoot());
		
		System.out.println("object1: "+object1);
		System.out.println("object2: "+object2);
		
		System.out.println("-----------------");
		
		Object object3 = Ognl.parseExpression("#person.name");
		Object object4 = Ognl.getValue(object3, ognlContext,ognlContext.getRoot());
		
		System.out.println("object3: "+object3);
		System.out.println("object4: "+object4);
		
		System.out.println("-----------------");
		
		Object object5 = Ognl.parseExpression("#dog.name");
		Object object6 = Ognl.getValue(object5, ognlContext,ognlContext.getRoot());
		
		System.out.println("object5: "+object5);
		System.out.println("object6 "+object6);
		
		System.out.println("----------------");
		
		person.setDog(dog);//为person设置dog属性
		
		Object object7 = Ognl.parseExpression("dog.name");
		Object object8 = Ognl.getValue(object7, ognlContext,ognlContext.getRoot());
		
		System.out.println("object7: "+object7);
		System.out.println("object8: "+object8);
		
	}
上面代码将person对象设置为root,那么在输入表达式时,如果不使用“#”开头,那么ognl则会从设置的root对象当中去调用属性的get方法,直接获取值,如果使用“#”开头,那么则会从“#”后面当中的对象中获取值,所以上面程序运行的结果为:

object1: name
object2: 张三
-----------------
object3: #person.name
object4: 张三
-----------------
object5: #dog.name
object6 旺财
----------------
object7: dog.name
object8: 旺财
ognl当中一样可以指定调用对象的方法,如下:

Object object9 = Ognl.parseExpression("name.substring(0, 1)");
Object object10 = Ognl.getValue(object9, ognlContext,ognlContext.getRoot());
		
System.out.println("object9: "+object9);
System.out.println("object10: "+object10);
上面代码运行后的结果为:

object9: name.substring(0, 1)
object10: 张

Ognl调用静态方法和静态成员变量

ognl当中调用静态方法,表达式需要用到两个“@”符号,而且@与@中间要放置该静态方法所属的类的全称(包括包名),

表达式为:@packnage.className@methodName(params)举例如下:

Object object11 = Ognl.parseExpression("@java.lang.Integer@toBinaryString(10)");
Object object12 = Ognl.getValue(object11,ognlContext, ognlContext.getRoot());
		
System.out.println("object11: "+object11);
System.out.println("object12: "+object12);
输出结果为:

object11: @java.lang.Integer@toBinaryString(10)
object12: 1010

对于OGNL来说,java.lang.Math是其默认类,如果调用java.lang.Math的静态方法,则不需要特别指定其类,如:

Object object13 = Ognl.parseExpression("@@min(4,10)");
Object object14 = Ognl.getValue(object13, ognlContext,ognlContext.getRoot());
		
System.out.println("object13: "+object13);
System.out.println("object14: "+object14);
输出结果为:

object13: @java.lang.Math@min(4, 10)
object14: 4

ognl同样可以访问类的静态成员变量:

		Object object15 = Ognl.parseExpression("@@PI");
		Object object16 = Ognl.getValue(object15, ognlContext,ognlContext.getRoot());
		
		System.out.println("object13: "+object15);
		System.out.println("object14: "+object16);
输出结果为:

object13: @java.lang.Math@PI
object14: 3.141592653589793

Ognl集合使用

对于ognl来说数组和集合是一样的,都是通过下标索引去访问。构造集合的时候使用{...}形式:

        Object object17 = Ognl.getValue("{'aa','bb','cc','dd'}", ognlContext,ognlContext.getRoot());
        
        System.out.println("object17: "+object17);
        
        Object object18 = Ognl.getValue("{'aa','bb','cc','dd'}[2]", ognlContext,ognlContext.getRoot());
        
        System.out.println("object18: "+object18);
object17: [aa, bb, cc, dd]
object18: cc
		List<String> friends = new ArrayList<String>();
		friends.add("aa");
		friends.add("bb");
		friends.add("cc");
		dog.setFriends(friends);
		
		Object object19 = Ognl.getValue("#dog.friends[1]", ognlContext,ognlContext.getRoot());
		
		System.out.println("object19: "+object19);
object19: bb

		List<String> list = new ArrayList<String>();
		list.add("hello");
		list.add("world");
		list.add("hello world");
		
		ognlContext.put("list", list);
		
		Object object20 = Ognl.getValue("#list[0]", ognlContext,ognlContext.getRoot());
		
		System.out.println("object20: "+object20);
object20: hello

Ogl处理映射(Map)

使用ognl处理映射(Map)时得语法格式如下

#{‘key1’:'value1','key2':'value2','key3':'value3'}

	        Map<String, String> map = new HashMap<String, String>();
		map.put("key1","value1");
		map.put("key2","value2");
		map.put("key3","value3");
		map.put("key4","value4");
		
		ognlContext.put("map", map);
		
		Object object21 = Ognl.getValue("#map['key3']", ognlContext,ognlContext.getRoot());
		
		System.out.println(object21);

过滤(filtering):collection.{? expression}

		List<Person> persons = new ArrayList<Person>();
		
		Person p1 = new Person();
		Person p2 = new Person();
		Person p3 = new Person();
		
		p1.setName("zhangsan");
		p2.setName("lisi");
		p3.setName("wangwu");
		
		persons.add(p1);
		persons.add(p2);
		persons.add(p3);
		
		ognlContext.put("persons", persons);
		
		//#this表示当前集合的对象,相当于java中的增强for循环
		//object22是集合
		Object object22 = Ognl.getValue("#persons.{? #this.name.length() > 4}", ognlContext,ognlContext.getRoot());
		Object object23 = Ognl.getValue("#persons.{? #this.name.length() > 4}.size", ognlContext,ognlContext.getRoot());
		Object object24 = Ognl.getValue("#persons.{? #this.name.length() > 4}.size()", ognlContext,ognlContext.getRoot());
		Object object25 = Ognl.getValue("#persons.{? #this.name.length() > 4}[0].name", ognlContext,ognlContext.getRoot());
		
		System.out.println("object22: "+object22);
		System.out.println("object23: "+object23);
		System.out.println("object24: "+object24);
		System.out.println("object25: "+object25);
object22: [com.iron.ognl.Person@122cdb6, com.iron.ognl.Person@1ef9157]
object23: 2
object24: 2
object25: zhangsan

OGNL针对集合提供了一些伪属性(如size,isEmpty),让我们可以通过属性的方式来调用方法(本质原因在于集合当中的很多方法并不符合JavaBean的命名规则),但我们依然可以通过调用方法来实现与伪属性相同的目的。

        //获取集合中的第一个元素,collection.{^ expression},返回的仍然是集合,只不过只有一个元素
        Object object26 = Ognl.getValue("#persons.{^ #this.name.length() > 4}", ognlContext,ognlContext.getRoot());
        Object object27 = Ognl.getValue("#persons.{^ #this.name.length() > 4}[0].name", ognlContext,ognlContext.getRoot());
        
        System.out.println(object26);
        System.out.println(object27);
[com.iron.ognl.Person@122cdb6]
zhangsan

		//获取集合中的最后一个元素,collection.{$ expression},返回的仍然是集合,只不过只有一个元素
		Object object28 = Ognl.getValue("#persons.{$ #this.name.length() > 4}", ognlContext,ognlContext.getRoot());

投影(projection):collection.{expression}

过滤和投影的区别是:类比于表的查询操作,过滤是取行操作,投影则是取列操作。

		System.out.println(Ognl.getValue("#persons.{name}", ognlContext,ognlContext.getRoot()));
		
		System.out.println(Ognl.getValue("#persons.{name.length() > 5 ? name : 'hello'}", ognlContext,ognlContext.getRoot()));
[zhangsan, lisi, wangwu]
[zhangsan, hello, wangwu]








  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值