1. OGNL表达式 (对象图导航语言)
OGNL是Object-Graph Navigation Language的缩写,翻译过来就是 对象视图导航语言 ,
它是一种功能强大的表达式语言,通过它简单一致的表达式语法,可以实现:
- 可以存取对象的任意属性,
- 可以调用对象的方法,
- 遍历整个对象的结构图,
- 实现字段类型转化等功能。
- 它使用相同的表达式去存取对象的属性。
EL(Expression Language) 是为了使JSP写起来更加简单。
表达式语言的灵感来自于 ECMAScript 和 XPath 表达式语言,它提供了在 JSP 中简化表达式的方法,让Jsp的代码更加简化。
EL表达式只能进行读取数据,
而OGNL不仅可以读取数据,更重要是是可以写入数据(赋值)、调用方法 (对象的一般方法、静态方法等);
OGNL表达式代码是由两部分组成的,分别是roo区域t和contextMap区域 ,root是对象栈,context是map值栈,这两个栈合并使用才算是一个完整的OGNL表达式,如下图所示:
注意:OGNL并不是struts本身的组件,是一个独立的技术。
struts2框架中使用的表达式并不是EL表达式,不是不能用,而是struts2有自己的一套御用的表达式,名字就叫OGNL表达式,这是struts直接把ognl直接拿过来用了,但并不是struts本身的。
下面通过实例代码在java代码中看如何从root区获取数据
要在Myeclipse中建立一个java project 并且建一个lib的文件夹导入ognl 的jar包。
1,从root区获取数据
主要实例如下:
其中person实体类有:
public class Person { private String name; private Integer age; private String sex; private String mobile; private Address address; private List<String> favorites; private Map<String,Integer> scores; getter 和setter方法,构造方法省略
Address实体类有:
public class Address { private String street; private String zipCode; getter 和setter方法,构造方法省略
然后测试类如下:
import com.macw.test; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import ognl.Ognl; import ognl.OgnlException; import com.macw.entity.Address; import com.macw.entity.Person; public class TestOgnl1 { public static void main(String[] args) throws OgnlException { //通过ongl从root区(对象)中获取属性值 Address address = new Address("丰乐路博颂路","450000"); Person p = new Person("xushy",18,"男","18530031576",address); //获取name属性 p.getName(); //获取street子属性 p.getAddress().getStreet(); //获取root区的属性 System.out.println(Ognl.getValue("name", p)); //获取root区对象的属性的子属性 System.out.println(Ognl.getValue("address.street", p)); List<String> favorites = new ArrayList<String>(); Collections.addAll(favorites, "唱","跳","rap","篮球"); p.setFavorites(favorites); //获取p对象的List集合属性的某一个元素 System.out.println(Ognl.getValue("favorites[0]", p)); Map<String,Integer> scores = new HashMap<String,Integer>(); scores.put("语文", 100); scores.put("数学",60); scores.put("英语", 85); p.setScores(scores); //获取Map属性的键值对数据 System.out.println(Ognl.getValue("scores[\"语文\"]", p)); System.out.println(Ognl.getValue("scores['语文']", p)); //Ognl的运算 /* * 数学运算 + - * / % * 比较运算 > >= < <= == != * 逻辑运算 && || ! * 三目运算符: ? : */ System.out.println(Ognl.getValue("age > 16", p)); System.out.println(Ognl.getValue("age + 16", p)); System.out.println(Ognl.getValue("age >= 18 ? '青年':'少年'", p)); //Ognl表达式调用方法 System.out.println(Ognl.getValue("name.toUpperCase()",p)); System.out.println(Ognl.getValue("name.length()", p)); System.out.println(Ognl.getValue("favorites.size()", p)); System.out.println(Ognl.getValue("name.charAt(0)", p)); } }
从中可以看到,ognl表达式获取数据语法为:
Ognl.getValue("属性名", 对象)
2,从从contextMap中获取数据
实体类还和上面的一样,用person对象和address对象
public class TestOgnl2 { public static void main(String[] args) throws OgnlException { //contextMap区 map集合 Address address = new Address("河南农业大学","450000"); Person p = new Person("macw",18,"男","13598051718",address); Map<String,Object> map = new HashMap<String,Object>(); map.put("p", p); System.out.println(Ognl.getValue("#p", map, new Object())); System.out.println(Ognl.getValue("#p.name", map,new Object())); System.out.println(Ognl.getValue("#p.address.zipCode", map,new Object())); List<String> favorites = new ArrayList<String>(); Collections.addAll(favorites, "唱","跳","rap","篮球"); p.setFavorites(favorites); System.out.println(Ognl.getValue("#p.favorites[0]", map,new Object())); Map<String,Integer> scores = new HashMap<String,Integer>(); scores.put("语文", 100); scores.put("数学",60); scores.put("英语", 85); p.setScores(scores); System.out.println(Ognl.getValue("#p.scores['英语']", map,new Object())); } }
获取ContextMap中的数据:
Ognl.getValue("#对象名", map,new Object()
1.到contextmap区域获取ognl表达式的语法需要以#为前缀。
2.#后面跟map里面的key。
3.Key后面跟root区域取数据的语法是一模一样的。