Ognl表达式语言

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Ognl表达式语言相关的知识,希望对你有一定的参考价值。

OGNL表达式

       OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写,它是一个开源项目。 Struts2框架使用OGNL作为默认的表达式语言。

OGNL优势

      1、支持对象方法调用,如xxx.doSomeSpecial();

       2、支持类静态的方法调用和值访问,表达式的格式:

             @[类全名(包括包路径)]@[方法名 |  值名],例如:

             @[email protected](‘foo %s‘, ‘bar‘)

             或@[email protected]_NAME;

       3、支持赋值操作和表达式串联,如price=100, discount=0.8,

             calculatePrice(),这个表达式会返回80;

       4、访问OGNL上下文(OGNL context)和ActionContext;

       5、操作集合对象。

OGNL 有一个上下文(Context)概念,说白了上下文就是一个MAP结构,它实现了java.utils.Map 的接口。
OgnlContext类【本质是一个Map】

分析:Struts框架默认就支持Ognl表达式语言。(struts必须引用的包:ognl.jar)


OgnlContext是Struts2的数据中心。

当Struts2接受一个请求时,会迅速创建ActionContext、ValueStack和Action对象。然后把action存放进ValueStack,所以action的实例变量可以被OGNL访问。 示意图如下

技术分享

可以打开OglnContext的源代码,如下:

public class OgnlContext extends Object implements Map
{
    public static final String          CONTEXT_CONTEXT_KEY = "context";
    public static final String          ROOT_CONTEXT_KEY = "root";
    public static final String          THIS_CONTEXT_KEY = "this";
    .......
}

 有一个特点是继承自Map接口

现在可以写一写其测试类:

package com.gqx.ognl;

import ognl.Ognl;
import ognl.OgnlContext;
import ognl.OgnlException;

import org.junit.Test;

public class OgnlTest {
	/**
	 * 使用Ognl表达式取值,取非根元素的值,必须要用"#"
	 */
	@Test
	public void test() {
		//创建一个OgnlContext上下文对象
		OgnlContext context=new OgnlContext();
		//存放数据,继承自map接口,所以map形式存放
		context.put("name", "gqxing");
		//获取数据
		String value=(String) context.get("name");
		System.out.println(value);
	}
	
	@Test
	public void test2() throws OgnlException {
		//创建一个OgnlContext上下文对象
		OgnlContext context=new OgnlContext();
		//存放数据,继承自map接口,所以map形式存放
		User user=new User();
		user.setId(101);
		user.setName("gqxing");
		context.put("user", user);
		//获取数据
		/*
		 * 第一种方式:
		User value=(User) context.get("user");
		System.out.println(user.getName()+":"+user.getId());
		*
		*第二种方式
		*先构建一个ognl表达式,在解析表达式
		*/
		//向非根元素取值是,要用"#"号
		Object ognl=Ognl.parseExpression("#user.id");
		Object value=Ognl.getValue(ognl, context, context.getRoot());
		System.out.println(value);	
	}
	
	/**
	 * Ognl表达式语言语言取值,取根元素的值,不用带#号
	 * @throws OgnlException
	 */
	@Test
	public void test3() throws OgnlException {
		//创建一个OgnlContext上下文对象
		OgnlContext context=new OgnlContext();
		//存放数据,继承自map接口,所以map形式存放
		User user=new User();
		user.setId(101);
		user.setName("gqxing");
		context.put("user", user);
		//设置根元素,向根元素放数据
		context.setRoot(user);
		//获取数据(map)
		//向根元素取值是,直接写属性
		Object ognl=Ognl.parseExpression("id");
		Object value=Ognl.getValue(ognl, context, context.getRoot());
		System.out.println(value);	
	}
	
	/**
	 * 获取属性之下的属性 
	 * @throws OgnlException
	 */
	@Test
	public void test4() throws OgnlException {
		//创建一个OgnlContext上下文对象
		OgnlContext context=new OgnlContext();
		//存放数据,继承自map接口,所以map形式存放
		User user=new User();
		user.setId(101);
		user.setName("gqxing");
		context.put("user", user);
		//设置根元素,向根元素放数据
		context.setRoot(user);
		//获取数据(map)
		//向根元素取值是,直接写属性
		Object ognl=Ognl.parseExpression("address.province");
		Object value=Ognl.getValue(ognl, context, context.getRoot());
		System.out.println(value);	
	}
	
	
	/**
	 * 静态方法调用 
	 * @throws OgnlException
	 */
	@Test
	public void test5() throws OgnlException {
		OgnlContext context =new OgnlContext();
		//Ognl表达式语言,调用静态方法
		//Object ognl=Ognl.parseExpression("@[email protected](5.6)");
		//由于Math类在开发中用的比较多,所以可以这样写
		Object ognl=Ognl.parseExpression("@@floor(5.6)");
		Object value=Ognl.getValue(ognl, context,context.getRoot());
		System.out.println(value);
	}

}

 


 Struts2的值栈ValueStack

ValueStack即值栈对象,是整个数据存储的核心,或叫中转站。实现了该接口的OgnlValueStack类。
ValueStack特点
        ValueStack贯穿整个 Action 的生命周期(每个 Action 类的对象实例都拥有一个ValueStack 对象). 相当于一个数据的中转站. 在其中保存当前Action 对象和其他相关对象. Struts2框架把 ValueStack 对象保存在名为 “struts.valueStack” 的request请求属性中,传入jsp页面。开发者只需通过ActionContext对象就可以直接去访问struts的其他关键对象,(ActionContext是专门给开发者使用的,便于学习和使用)

 可以写一个Action来测试其中的关系

package com.gqx.ognl;

import javax.servlet.ServletRequest;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.util.ValueStack;

/**
 * struts的数据流转
 * @author GQXing
 *
 */
public class OgnlDemo  extends ActionSupport{
	@Override
	public String execute() throws Exception {
		//值栈对象存储数据的原理:
		ActionContext actionContext=ActionContext.getContext();
		ValueStack valueStack2=actionContext.getValueStack();
		System.out.println(valueStack2);
		return SUCCESS;
	}

	public String test(){
		//获取值栈对象。方式一:
		ServletRequest request=ServletActionContext.getRequest();
		ValueStack valueStack=(ValueStack) request.getAttribute("struts.valueStack");
		//获取值栈对象。方式二
		ActionContext actionContext=ActionContext.getContext();
		ValueStack valueStack2=actionContext.getValueStack();
		System.out.println(valueStack==valueStack2);  //true
		return SUCCESS;
	}
}

 加入断点调试,可以看到相应的变量值

技术分享

 

 

 

 

 

 

 

 

 








以上是关于Ognl表达式语言的主要内容,如果未能解决你的问题,请参考以下文章

OGNL与值栈

什么是Ognl

OGNL_一点

OGNL的全称是对象图导航语言

Struts2整合OGNL

Struts2高级开发之OGNL