同以往的技术相比,OGNL有哪些优势呢?总结起来有如下几个方面。
OGNL是将视图元素(例如textfield、combobox等)同模型对象绑定在一起的一种语言。使用OGNL的类型转换功能,会使类型转换变得更加简单(例如将一个字符串类型转换为一个整数类型)。
表格元素同Swing TableModel对应的一种数据源语言。
可以将Web页面元素同后台服务器业务对象对应起来。
比JSTL(JSP标准标签库)表达更加丰富。
8.1.2 OGNL语法
基本的OGNL语法是十分简单的,当然OGNL支持丰富的表达式,一般情况下,不用担心OGNL的复杂性。例如有一个man对象,该对象有一个name属性,那么使用OGNL来获得该name属性可以使用如下表达式:
man.name |
OGNL表达式的基础单元称为导航链,简称为链。一个最简单的链由如下部分组成。
属性名称:如上述示例中的name。
方法调用:hashCode()返回当前对象的hash code。
数组元素:listeners[0]返回当前对象的监听器列表中的第一个元素。
★ 说明 ★
OGNL表达式基于OGNL上下文中的当前对象,一个“链”将使用上一个“链”的处理结果,开发者可以任意扩展该链的长度,OGNL没有限制。
例如,一个OGNL表达式如下:
name.toCharArray()[0].numericValue.toString() |
该表达式将按照如下步骤求值。
(1)获得OGNL Context中初始对象或者是根对象(root对象)的name对象。
(2)调用toCharArray()方法,返回一个String类型对象。
(3)获得该String对象的第一个字符。
(4)获得该字符的numericValue属性(该字符为一个Character对象,该对象有一个getNumericValue()方法,该方法返回一个Integer类型值)。
(5)将获得的Integer对象转换为一个String类型值(使用toString()方法)。
8.1.3 一个使用OGNL的示例
下面笔者以一个简单的示例来帮助读者理解OGNL表达式。使用OGNL表达式,需要在www.ognl.org网站下载一个ognl.jar插件包,将该文件复制到classpath路径下即可。建立一个复合类型,如代码8.1所示。
代码8.1 定义复合类型
package ch8; import java.util.Date; //团队类 public class Team { // 团队名称 private String teamname; // 定义团队人员属性 private Person person; // 团队人数 private int personnum; //属性的getter和setter方法 public String getTeamname() { return teamname; } public void setTeamname(String teamname) { this.teamname = teamname; } public Person getPerson() { return person; } public void setPerson(Person person) { this.person = person; } public int getPersonnum() { return personnum; } public void setPersonnum(int personnum) { this.personnum = personnum; } } // 定义人员类 class Person { // 姓名 private String name; // 年龄 private int age; // 人员出生日期 private Date birthday; //属性的getter和setter方法 public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } } |
代码8.1所示内容定义了两个复合类型:团队(team)和人员(person)类型。使用OGNL表达式示例,如代码8.2所示。
代码8.2 使用OGNL表达式示例
package ch8; import java.util.HashMap; import java.util.Map; import ognl.Ognl; import ognl.OgnlException; public class TestOGNL { public static void main(String[] args) { //定义一个Map对象 Map m = new HashMap(); //定义一个Team对象 Team team1 = new Team(); team1.setTeamname("团队1"); //定义一个Person对象 Person person1 = new Person(); person1.setName("pla1"); //添加team元素 team1.setPerson(person1); //定义一个Team对象 Team team2 = new Team(); team2.setTeamname("团队2"); //定义一个Person对象 Person person2 = new Person(); person2.setName("pla2"); //添加team元素 team2.setPerson(person2); //添加Map元素 m.put("team1", team1); m.put("team2", team2); try { System.out.println(Ognl.getValue("team1.teamname", m)); System.out.println(Ognl.getValue("team2.person.name", m)); System.out.println(Ognl.getValue("teamname", team2)); System.out.println(Ognl.getValue("person.name", team2)); } catch (OgnlException e) { } } } |
代码8.2所示内容定义了一个Map类型的嵌套属性,如图8.1所示。
图8.1 嵌套属性示意图 |
团队1 pla2 团队2 pla2 |
★ 说明 ★
OGNL可以使用非常简单的表达式来访问多层嵌套属性,为开发者提供了一个有力的工具。