OGNL是Object-Graph Navigation Language的缩写,全称为对象图导航语言,是一种功能强大的表达式语言,它通过简单一致的语法,可以任意存取对象的属性或者调用对象的方法,能够遍历整个对象的结构图,实现对象属性类型的转换等功能。从语言角度来说:它是一个功能强大的表达式语言,用来获取和设置java 对象的属性 , 它旨在提供一个更高抽象度语法来对 java 对象图进行导航,OGNL 在许多的地方都有应用,例如:
- 作为 GUI元素(textfield,combobox,等)到模型对象的绑定语言。
- 数据库表到 Swing的 TableModel的数据源语言。
- web组件和后台 Model对象的绑定语言 (WebOGNL,Tapestry,WebWork,WebObjects)。
- 作为 Jakarata Commons BeanUtils或者 JSTL的表达式语言的一个更具表达力的替代语言。
另外,java中很多可以做的事情,也可以使用 OGNL 来完成,例如:列表映射和选择。对于开发者来说,使用 OGNL,可以用简洁的语法来完成对 java对象的导航。通常来说: 通过一个“路径”来完成对象信息的导航,这个“路径”可以是到 java bean的某个属性,或者集合中的某个索引的对象,等等,而不是直接使用 get或者 set 方法来完成。
为什么需要表达式语言 (EL)
表达式语言(EL)本质上被设计为:帮助你使用简单的表达式来完成一些“常用”的工作。通常情况下,ELs可以在一些框架中找到,它被是用来简化我们的工作。例如:大家熟知的 Hibernate,使用HQL(Hibernate Query Language)来完成数据库的操作,HQL 成了开发人员与复查的 SQL表达式之间的一个桥梁。 在 web框架下,表达式语言起到了相似的目的。它的存在消除了重复代码的书写。例如:当没有 EL的时候,为了从 session 中得到购物车并且将 ID在网页上呈现出来,当直接在 jsp 中使用 java代码来完成的时候,一般是:
<%
ShoppingCart cart = (ShoppingCart) session.get("cart");
int id = cart.getId();
%>
<%= id%>
你也可以将这些 code压缩成一句,如下,但是现在代码就很不直观,且不可读。另外,虽然变成了一句,但是与上面的原始的例子一样,也包含了同样的表达式。例如:类型转换:转换成 ShoppingCart。这里只不过是将原来的三个表达式变成了一句,其复杂度是没有得到简化的。
<%= ((ShoppingCart) session.get("cart")).getId() %>
当在 web框架中使用表达式语言的时候,则可以有效的处理这种代码的复杂性。而不需要你,调用 servelet API,类型转换,然后再调用getter方法,多数的 Els 都可将这个过程简化为类似于:#session.cart.id这中更可读的表达式。表达式:#session.cart.id与 java 代码不一样的是:没有 java代码的 get 方法调用和类型转换。因为这些操作是非常“常用”的,这时候使用 EL就顺理成章了,使用 EL 可以“消除”这些代码。
此外,还得先需弄懂OGNL的一些知识:
1.OGNL表达式的计算是围绕OGNL上下文进行的。
OGNL上下文实际上就是一个Map对象,由ognl.OgnlContext类表示。它里面可以存放很多个JavaBean对象。它有一个上下文根对象。
上下文中的根对象可以直接使用名来访问或直接使用它的属性名访问它的属性值。否则要加前缀“#key”。
2.Struts2的标签库都是使用OGNL表达式来访问ActionContext中的对象数据的。如:<s:propertyvalue="xxx"/>。
3.Struts2将ActionContext设置为OGNL上下文,并将值栈作为OGNL的根对象放置到ActionContext中。
4.值栈(ValueStack):
可以在值栈中放入、删除、查询对象。访问值栈中的对象不用“#”。
Struts2总是把当前Action实例放置在栈顶。所以在OGNL中引用Action中的属性也可以省略“#”。
5.调用ActionContext的put(key,value)放入的数据,需要使用#访问。
OGNL中重要的3个符号:#