深入理解Struts2(十三):探讨OGNL(上篇)
什么是OGNL
OGNL,即Object Graphic Navigation Language,对象图导航语言,它是Struts2的默认表达式语言
使用OGNL需要导入OGNL的jar包:ognl-3.1.26.jar
OGNL与EL比较相似,但它比EL要强大得多
操作的对象
EL操作的对象是四个域对象,即pageContext、request、session、application,${user.username}中user就是从四个域中查找
而OGNL操作的对象有两个:OgnlContext(Map)、Root(根对象)
OGNL入门
创建OGNL上下文对象,它是一个Map:
OgnlContxt context = new OgnlContext();
向OgnlContext中添加数据:
context.put("e1",emp1);
指定OGNL根对象:
context.setRoot(emp1);
使用Ognl.getValue():
三个参数分别为
(1)ognl表达式
(2)ognl上下文对象
(3)ognl根对象
表达式
(1)以#开头,表示获取的是上下文中的数据
(2)不以#开头,表示获取的是根对象的数据
例子
public class Demo1 {
static OgnlContext getContext() {
OgnlContext context = new OgnlContext();
Emp e1 = new Emp();
e1.setName("张三");
e1.setAddress(new Address("中国","广州市","凤阳街道"));
e1.setSalary(20000);
Emp e2 = new Emp();
e2.setName("李四");
e2.setAddress(new Address("中国","潮州市","丁未路"));
e2.setSalary(15000);
//OgnlContext是一个Map,添加元素
context.put("e1", e1);
context.put("e2", e2);
//设置OgnlContext的root元素
context.setRoot(e1);
return context;
}
@Test
public void fun1() throws OgnlException {
OgnlContext context = getContext();
/*
* getValue()需要传三个参数
* 1.ognl表达式
* 2.ognl上下文对象
* 3.ognl根对象
* */
//从上下文中获取指定元素的属性
String name = (String) Ognl.getValue("#e2.name",context,context.getRoot());
System.out.println(name);
String city = (String) Ognl.getValue("#e2.address.city",context,context.getRoot());
System.out.println(city);
//当ognl表达式不以#开头,而是自己写属性的名字时,代表拿的是根对象的属性
String rootName = (String)Ognl.getValue("address.country",context,context.getRoot());
System.out.println(rootName);
}
}
常量
字符串常量:可以用单引号或者双引号,但要注意,如果字符串只有一个字符的话,必须使用双引号
字符常量:使用单引号
数字常量:与Java相同
boolean常量:与Java相同
null常量:与Java相同
例子:
@Test
public void fun2() throws OgnlException {
OgnlContext context = getContext();
String nameConst = (String) Ognl.getValue("'name'", context,context.getRoot());
//结果就是name,因为name外面有单引号,表示一个字符串常量
System.out.println(nameConst);
}
运算符
大多数和java一样
逗号:多个表达式之间用逗号分隔,如:1+2,3+4,name
1+2是和java相同的运算符,结果是数字常量3,name不以#开头,表示OgnlContext的根元素的属性
用逗号隔开的表达式,最右边的表达式是整个式子的值,如上面的式子结果就是根元素的name属性,即“张三”
例子:
@Test
public void fun2() throws OgnlException {
OgnlContext context = getContext();
String nameConst = (String) Ognl.getValue("'name'", context,context.getRoot());
//结果就是name,因为name外面有单引号,表示一个字符串常量
System.out.println(nameConst);
//结果是张三
System.out.println(Ognl.getValue("1+2,3+4,name",context,context.getRoot()));
//结果是7
System.out.println(Ognl.getValue("1+2,name,3+4",context,context.getRoot()));
}
大括号:用来创建List
例子:
@Test
public void fun3() throws OgnlException {
OgnlContext context = new OgnlContext();
Emp emp1 = new Emp("张三",20000,new Address("中国","广东","广州"));
Emp emp2 = new Emp("张三",20000,new Address("中国","广东","广州"));
context.put("e1",emp1);
context.put("e2",emp2);
context.setRoot(emp1);
Object o = Ognl.getValue("{'abc',123,false}",context,context.getRoot());
//o是List集合
System.out.println(o.getClass());
System.out.println(o);
}
in和not in:
- in:指定某个值是否在集合中存在,返回boolean类型
- not in :指定某个值是否在集合中不存在,返回boolean类型
例子:
@Test
public void fun4() throws OgnlException {
OgnlContext context = new OgnlContext();
Emp emp1 = new Emp("张三",20000,new Address("中国","广东","广州"));
Emp emp2 = new Emp("张三",20000,new Address("中国","广东","广州"));
context.put("e1",emp1);
context.put("e2",emp2);
context.setRoot(emp1);
//判断OGNL根对象的name属性值是否在集合{“张三”,123,false}中,结果返回true
boolean result = (boolean) Ognl.getValue("name in {\"张三\",123,false}",context,context.getRoot());
System.out.println(result);
}
设置javabean属性值
使用Ognl.setValue():
四个参数分别为
(1)指定javabean的属性的ognl表达式
(2)ognl上下文对象
(3)ognl根对象
(4)要设置的javabean的属性的值
例子:
@Test
public void fun5() throws OgnlException {
OgnlContext context = new OgnlContext();
Emp emp1 = new Emp("张三",20000,new Address("中国","广东","广州"));
Emp emp2 = new Emp("张三",20000,new Address("中国","广东","广州"));
context.put("e1",emp1);
context.put("e2",emp2);
context.setRoot(emp1);
Ognl.setValue("#e2.name",context,context.getRoot(),"燕子李四");
System.out.println(emp2);
}
之前在介绍模型驱动的时候,是这样写的:<input type="text" name="user.username"/>
这其实就调用了Ognl的setValue()方法
注意这里并没有写#,也就意味着设置给了根对象,
其实,Action就是根对象,这个在后面涉及到Struts2的Ognl时会详细介绍。