Struts2的ognl学习(转)

  学习Struts2的时候,觉得OGNL表达式语言很抽象,看了李刚的《Struts2.1权威指南》,感觉讲得不是很好。后来看了一位高手写的Struts2的文章,才有了一些头绪。
    Struts2的OGNL表达式语言是基于Xwork的OGNL的,它在Xwork的基础上对OGNL进行了一些封装,因此先了解Xwork的OGNL是十分有必要的。Xwork的OGNL使用时比较容易理解。它有两个重要的概念:上下文环境和根对象。上下文环境是一个Map对象,所有的数据存取都是在上下文环境中进行的,你可以在存取数据时指定不同Map作为上下文环境。访问根对象时不需要加#前缀,而访问上下文环境中的其它对象需要加入#前缀。
Xwork中的OGNL通过Ognl类操作数据。

Java代码 复制代码  收藏代码
  1. public void testGetValue() throws Exception{   
  2.         User user = new User();   
  3.         user.setId(1);   
  4.         user.setName("lijie");    
  5.   
  6.         Object name = Ognl.getValue(Ognl.parseExpression("name"), user);   
  7.         System.out.println(name);   
  8.     }  
public void testGetValue() throws Exception{
		User user = new User();
		user.setId(1);
		user.setName("lijie"); 

		Object name = Ognl.getValue(Ognl.parseExpression("name"), user);
		System.out.println(name);
	}


以上代码将User作为根对象(可以参见Ognl的API),访问其name属性,所以不需要前缀#,输出lijie。

Java代码 复制代码  收藏代码
  1. public void testGetValue() throws Exception{   
  2.         User user = new User();   
  3.         user.setId(1);   
  4.         user.setName("lijie");   
  5.            
  6.         Map context = new HashMap();   
  7.         context.put("user", user);   
  8.            
  9.     Object name = Ognl.getValue(Ognl.parseExpression("name"), context,user);   
  10.         System.out.println(name);    
  11.     }  
public void testGetValue() throws Exception{
		User user = new User();
		user.setId(1);
		user.setName("lijie");
		
		Map context = new HashMap();
		context.put("user", user);
		
	Object name = Ognl.getValue(Ognl.parseExpression("name"), context,user);
		System.out.println(name); 
	}


上述代码将Map对象context作为上下文,user是其中的根对象,所以直接访问name属性,输出lijie。

Java代码 复制代码  收藏代码
  1. public void testGetValue() throws Exception{   
  2.         User user = new User();   
  3.         user.setId(1);   
  4.         user.setName("lijie");    
  5.            
  6.         Map context = new HashMap();   
  7.         context.put("user", user);    
  8.         context.put("country""China");   
  9.            
  10.         Object country = Ognl.getValue(Ognl.parseExpression("#country"), context,user);   
  11.         System.out.println(country);            
  12.     }  
public void testGetValue() throws Exception{
		User user = new User();
		user.setId(1);
		user.setName("lijie"); 
		
		Map context = new HashMap();
		context.put("user", user); 
		context.put("country", "China");
		
		Object country = Ognl.getValue(Ognl.parseExpression("#country"), context,user);
		System.out.println(country);		 
	}


上述代码在context上下文中加入了一个String对象country,由于country不是根对象,所以访问时必须加前缀#,否则会抛出异常,指明根对象中没有country属性。上述代码输出China。

Java代码 复制代码  收藏代码
  1. public void testGetValue() throws Exception{   
  2.         User user = new User();   
  3.         user.setId(1);   
  4.         user.setName("lijie");     
  5.             
  6.         Ognl.setValue("name", user, "Tom");   
  7.         System.out.println(user.getName());      
  8.     }  
public void testGetValue() throws Exception{
		User user = new User();
		user.setId(1);
		user.setName("lijie");  
		 
		Ognl.setValue("name", user, "Tom");
		System.out.println(user.getName());	  
	}


上述代码向User对象设置,输出Tom。
    Struts2中的OGNL表达式语言是对Xwork的OGNL的封装。我们要理解一下几点:
1. Struts2中将ActionContext作为OGNL的上下文环境(ActionContext内部含有一个Map对象)
2. Struts2中的OGNL表达式语言的根对象是一个ValueStack,ValueStack中的每一个对象都被视为根对象。
Struts2框架将实例化的Action对象放入ValueStack中,如果是Action链,则多个Action都存在于ValueStack中。而ValueStack中除了Action外,Struts2框架还将parameters,request,response,session,application,attr等对象放到ActionContext中,访问这些对象需要加前缀#。

总结:Struts2中的数据处理基于Xwork的OGNL,它在OGNL的基础上进行了一定的封装。OGNL的核心概念是根对象(root)和上下文环境(context)---你可以传入一个Map对象作为上下文,向其中put进一个对象,那么这个对象可以作为根对象(ognl中可以向函数中传入不同的Map对象作为根对象来操作,也可以指定不同的根对象,而Struts2中,它固定了根对象ValueStack)。在Struts2中,ActionContext作为OGNL的上下文环境,它的根对象是一个ValueStack,ValueStack中的每个对象都被视为根对象。Struts2中的Action作为根对象存在(如果多个Action以chain的形式存在,则多个Action均存在于ValueStack中,均为根对象)。

以上是我大概的理解,具体的细节大家可以参考一些资料,不妥之处,希望大家批评指正。

猜你喜欢

转载自xiongzhenhui.iteye.com/blog/1047242