OGNL 是 Object-Graph Navigation Language 的缩写,从语言角度来说:它是一个功能强大的表达式语言(EL),用来获取和设置 java 对象的属性 , 它旨在提供一个更高抽象度语法来对 java 对象图进行导航。
Jsp 页面中的 jsp 标签就是一种表达语言。
目的
主要是用来解析 Mybatis 中 mapper.xml 文件中的表达式来使用。
语法
比如要获取一个对象的 name 属性,OGNL 表达式就是 name, 要获取一个对象的 headline 属性的 text 属性,OGNL 表达式就是 headline.text 。 OGNL 表达式的基本单位是”导航链”,往往简称为”链”。
- 取 java 对象的 name 属性
#{name}
${name}
name.toCharArray()[0].numericValue.toString()
表达式求值过程
- 提取根 (root) 对象的 name 属性。
- 调用上一步返回的结果字符串的 toCharArray() 方法。
- 提取返回的结果数组的第一个字符。
- 获取字符的 numericValue 属性,该字符是一个 Character 对象,
- Character 类有一个 getNumericValue() 方法。
- 调用结果 Integer 对象的 toString() 方法。
OGNL 表达式
- 常量: 字符串:” ello” 字符:’h’ 数字:除了像 java 的内置类型 int,long,float 和 double,Ognl 还有如例:10.01B,相当于 java.math.BigDecimal,使用 ‘b’ 或者 ‘B’ 后缀。 100000H,相当于 java.math.BigInteger,使用 ‘h’ 或 ‘H’ 后缀。
- 属性的引用 例如:user.name
- 变量的引用 例如:#name
- 静态变量的访问 使用 @class@field
- 静态方法的调用 使用 @class@method(args), 如果没有指定 class 那么默认就使用 java.lang.Math.
- 构造函数的调用 例如:new java.util.ArrayList();
OgnlContext
OgnlContext对象是ognl表达式语言的核心。
OGNL 有一个上下文(Context)概念,说白了上下文就是一个MAP结构,它实现了java.utils.Map 的接口。用来存储表达式对象的值。
举例
/**
* OgnlContext用法
* 1.使用Ognl表达式语言取值,如果取非根元素的值,必须用#号
* 2.使用Ognl表达式语言取值,如果取根元素的值,不用#号
* 3.Ognl可以调用静态方法
*/
public class OgnlDemo {
//非根元素
@Test
public void testOgnl1() throws OgnlException {
//创建一个Ognl上下文对象
OgnlContext context = new OgnlContext();
/**
* 1.OgnlContext放入基本变量数据
*/
//放入数据
context.put("cn","China");
//获取数据(map)
String value = (String)context.get("cn");
System.out.println(value);
/**
* 2.OgnlContext放入对象数据
*/
//创建对象,设置对象属性
User user = new User();
user.setId(100);
user.setName("Jack");
//【往非根元素放入数据,取值的时候表达式要用“#”】
context.put("user",user);
//获取对象属性
//使用这种方式也可以获取
Object s = context.get("user");
System.out.println(s);
//使用Ognl表达式来获取
//举例:例如标签<s:a value="#user.id">取值,实际上就是运行了下面的代码获取的
//先构建一个Ognl表达式,再解析表达式
Object ognl = Ognl.parseExpression("#user.id");//构建Ognl表达式
Object value1 = Ognl.getValue(ognl, context, context.getRoot());//解析表达式
System.out.println(value1);
User user1 = new User();
user1.setId(100);
user1.setName("Jack");
context.setRoot(user1);
Object ognl1 = Ognl.parseExpression("id");//构建Ognl表达式
Object value2 = Ognl.getValue(ognl1, context, context.getRoot());//解析表达式
System.out.println(value2);
}
//根元素
@Test
public void testOgnl2() throws OgnlException {
OgnlContext context = new OgnlContext();
User user1 = new User();
user1.setId(100);
user1.setName("Jack");
context.setRoot(user1);
//根元素直接使用id,不需要加#号
Object ognl1 = Ognl.parseExpression("id");//构建Ognl表达式
Object value2 = Ognl.getValue(ognl1, context, context.getRoot());//解析表达式
System.out.println(value2);
}
//ognl对静态方法调用的支持
@Test
public void testOgnl3() throws Exception{
//创建一个Ognl上下文对象
OgnlContext context = new OgnlContext();
//Ognl表达式语言,调用类的静态方法
// Object ognl = Ognl.parseExpression("@Math@floor(10.9)");
//由于Math类在开发中比较常用,所有也可以这样写
Object ognl = Ognl.parseExpression("@@floor(10.9)");
Object value = Ognl.getValue(ognl, context, context.getRoot());
System.out.println(value);
}
}
网友评论