1 什么是OGNL?
OGNL是Object-Graph Navigation Language的缩写(即对象图导航语言),它是一种功能强大的表达式语言,通过它简单一致的表达式语法,可以存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化等功能。它使用相同的表达式去存取对象的属性。
2 OGNL与EL的区别?
EL:从域对象中获取数据,从EL的11个对象中获取。
OGNL:可以调用对象的方法、可以从域对象中获取数据,可以获取Struts2的值栈的数据。OGNL其实是第三方的表达式语言(是单独的,即不属于Struts2的,是Struts2觉得OGNL表达式很好,因此把它引入框架中使用。因此没有Struts2框架,也可以用OGNL )
3 OGNL的优势
- 支持对象方法调用,如xxx.doSomeSpecial();
- 支持类静态的方法调用和值访问,表达式的格式为@[类全名(包括包路径)]@[方法名 | 值名],例如:@java.lang.String@format('foo %s', 'bar')或@tutorial.MyConstant@APP_NAME;
- 支持赋值操作和表达式串联,如price=100, discount=0.8, calculatePrice(price*discount),这个表达式会返回80;
- 访问OGNL上下文(OGNL context)和ActionContext;
- 操作集合对象
- 可以直接new一个对象
4 OGNL使用的要素
- 表达式
- 根对象
- Context对象
5 OGNL的Java入门
5.1 OGNL调用对象的方法
假设我们要利用OGNL表达式求“helloworld”字符串的长度,代码如下
package com.itykd.ognl;
import org.junit.Test;
import ognl.Ognl;
import ognl.OgnlContext;
import ognl.OgnlException;
public class OGNLDemo {
@Test
public void demo1() throws OgnlException{
//获得context对象
OgnlContext context = new OgnlContext();
//获得根对象
Object root = context.getRoot();
//执行表达式
Object obj = Ognl.getValue("'helloworld'.length()", context, root);
//输出结果
System.out.println(obj);
}
}
返回的结果是字符串的长度10;
5.2 OGNL访问对象的静态方法
假设我们要访问Math类的静态方法random:Math.random(),则需要输入完整的类和方法,类和方法名前面都要加@,对应的代码如下:
@Test
public void demo2() throws OgnlException{
//获得context对象
OgnlContext context = new OgnlContext();
//获得根对象
Object root = context.getRoot();
//执行表达式
Object obj=Ognl.getValue("@java.lang.Math@random()", context, root);
//输出结果
System.out.println(obj);
}
5.3 获取Root中的数据(不需要加#)
public void demo3() throws OgnlException {
//获取context对象
OgnlContext context = new OgnlContext();
//执行表达式
User user = new User("ykd","123456");
context.setRoot(user);
//获得根对象
Object root = context.getRoot();
//取出根对象的数据
Object username = Ognl.getValue("username", context, root);
Object password = Ognl.getValue("password", context, root);
System.out.println(username+" "+password);
}
5.4 获取context中的数据(需要加#)
@Test
public void demo4() throws OgnlException {
//获取context对象
OgnlContext context = new OgnlContext();
//获得根对象
Object root = context.getRoot();
//向context存入数据
context.put("name","ykd");
//取出context对象的数据
Object name = Ognl.getValue("#name", context, root);
System.out.println(name);
}
6 Struts2的ognl入门
6.1 调用对象的方法
这里将OGNL表达式应用于JSP页面中,首先需要在jsp页面中引入struts2的标签库,<%@ taglib uri="/struts-tags" prefix="s" %>,然后再使用对应的表达式;
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h3>OGNL在Struts2环境的入门</h3>
<s:property value="'struts2'.length()"/>
</body>
</html>
6.2 调用对象的静态方法
由于Struts2的ognl表达式访问对象静态方法默认是关闭的,因此需要进行开启设置
Struts2的常量是在default.properties(在Struts2-core.jar包下的org.apache.struts2中)属性文件中
如果要利用OGNL表达式调用对象的静态方法,需要开启静态方法访问,这里在struts.xml文件中进行开启
<struts>
<constant name="struts.ognl.allowStaticMethodAccess" value="true"/>
</struts>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h3>OGNL在Struts2环境的入门</h3>
<s:property value="@java.lang.Math@random()"/>
</body>
</html>