OGNL介绍

  何为OGNL? - HRY23大杂烩  06.11.07  阅读:172    公众公开     相关文章(14)    
OGNL 是Object-Graph Navigation Language的缩写,它是一种功能强大的表达式语言(Expression Language,简称为EL),通过它简单一致的表达式语法,可以存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化等功 能。如果一个OGNL表达式在括号前没有逗号,那么OGNL会把第一表达式的结果作为另一个表达式来赋值,而括号中表达式的结果会作为root object指向那个表达式。OGNL将Lambda表达式作为常量来处理。

基本概念 

OGNL全称是Object-Graph Navigation Language,是一个用来获取和设置JAVA对象的属性的表达式语言。通过使用表达式语法导航对象图,而不是直接调用对象的获取和设置方法可以提供许多应用。比如在XML文件或者脚本文件中嵌入OGNL表达式语法,在JSP页面展现层使用OGNL表达式语法。类似的应用有Velocity,Freemark,Webwork。

如何使用

最简单的使用是直接使用ognl.Ognl类来评估一个OGNL表达式。 Ognl类提供一些静态方法用来解析和解释OGNL表达式,最简单的示例是不使用上下文从一个对象中获取某个表达式的值,示例如下:


        
java 代码
  1.  import ognl.Ognlimport ognl.OgnlException;      
  2. try {           
  3.        result = Ognl.getValue(expression, root);       
  4. }    
  5. catch (OgnlException ex)    
  6. {          
  7.         // Report error or recover       
  8. }  

上述代码将基于root对象评估expression,返回结果,如果表达式有错,比如没有找到指定的属性,将抛出OgnlException。

更复杂一点的应用是使用预解析的表达式。这种方式允许评估表达式前捕获解析错误,也允许缓存解析出来的表达式进一个AST供重得使用从而提高性能。Ognl的parseExpression方法就是用来执行预解析操作的。

Ognl类的获取和设置方法大都可以接受一个context map参数,是一个Map类型的对象,允许你一些自己的变量进去,缺省的上下文里只包含#root和#context两个键。 Ognl内部会用这个Map替换OgnlContext类的缺省的map属性。Ognl的一些addDefaultContext方法就是完成这些功能的。

OgnlContext提供一些设置,可以更改OGNL的缺省行为,比如TypeConverter接口实例用来改变类型转换行为,具体可以参见相关文档。

下面的示例展示如何从root对象中解析出documentName属性,然后将当前用户名称添加到返回的结果后面:


       
java 代码
  1. private Map context = new HashMap();       
  2.   
  3. public void setUserName(String value)   
  4. {   
  5.     context.put("userName", value);   
  6. }        
  7.   
  8. ry {   
  9.    // get value using our own custom context map   
  10.    result = Ognl.getValue("userName"", context, root);   
  11. catch (OgnlException ex) {   
  12.     // Report error or recover   
  13. }  

基本语法

OGNL的语法正变得越来越丰富,但是基本语法是没有什么改变的。比如要获取一个对象的name属性,OGNL表达式就是name,要获取一个对象的headline属性的text属性,OGNL表达式就是headline.text。 

OGNL表达式的基本单位是导航链。最简单的链包含如下部分:

表达式组成部分 示例
属性名称 如上述示例中的name和headline.text
方法调用 hashCode()返回当前对象的哈希码。
数组元素 listeners[TEC:0]返回当前对象的监听器列表中的第一个元素。

所有的OGNL表达式都基于当前对象的上下文来评估,导航链的示例如下:


       
java 代码
  1. name.toCharArray()[0].numericValue.toString()  

评估步骤如下:

  • 解析根对象的name属性。
  • 调用上一步返回的结果字符串的toCharArray()方法。
  • 获取返回的结果数组的第一个字符,是一个Character对象。
  • 获取字符的数字值表示,Character有一个getNumericValue()方法。
  • 调用结果Integer对象的toString()方法。

参考资料

API文档

语言规范

开发指南

### OGNL表达式的基本概念 OGNL(Object-Graph Navigation Language)是一种功能强大的表达式语言,主要用于访问和操作Java对象的属性。它提供了一种简洁的方式来进行复杂的对象图导航与操作,支持变量、方法调用、集合操作等特性。这种表达式语言在许多框架中得到了广泛应用,例如MyBatis和Struts2。 OGNL的核心特点之一是其能够通过简单的语法对嵌套的对象结构进行高效访问。例如,可以通过`object.property.subProperty`的形式快速访问对象的深层属性。此外,OGNL还支持动态方法调用和集合操作,这使得开发者可以在表达式中直接调用方法或处理列表、数组等数据结构[^1]。 ### OGNL表达式的使用场景 #### 1. **Web框架中的数据绑定** 在MVC框架如Struts2中,OGNL被用来实现表单数据与Java对象之间的自动绑定。用户提交的表单数据可以通过OGNL表达式映射到对应的对象属性上,从而简化了数据处理的过程。例如,一个包含用户信息的表单可以自动填充到一个User对象中,而无需手动逐个设置属性值。 #### 2. **MyBatis中的条件查询** 在MyBatis中,OGNL表达式常用于构建动态SQL语句。通过OGNL表达式,可以根据不同的业务需求灵活生成SQL查询条件。例如,在XML配置文件中,可以使用`<if test="name != null">`来判断某个字段是否为空,并根据结果决定是否将其包含在SQL语句中。这种方式不仅提高了代码的可读性,也增强了SQL语句的灵活性和安全性。 ```xml <select id="selectUsers" resultType="User"> SELECT * FROM users <where> <if test="name != null"> AND name = #{name} </if> <if test="age != null"> AND age = #{age} </if> </where> </select> ``` #### 3. **模板引擎中的数据渲染** OGNL也被广泛应用于模板引擎中,用于将后端数据动态渲染到前端页面。例如,在Apache FreeMarker或Velocity等模板引擎中,开发者可以通过OGNL表达式轻松访问和展示复杂的数据结构。这种方式不仅提升了开发效率,也让页面内容更加动态化和个性化。 #### 4. **权限控制与逻辑判断** 在某些需要进行权限控制或复杂逻辑判断的应用场景中,OGNL表达式可以作为规则引擎的一部分。通过定义特定的表达式,系统可以在运行时动态评估用户的权限或执行特定的业务逻辑。例如,可以根据用户的角色动态生成不同的界面元素或执行不同的操作流程。 ### OGNL表达式的高级特性 OGNL还支持一些高级特性,这些特性进一步扩展了其应用场景。例如: - **Lambda表达式**:OGNL允许开发者在表达式中定义和使用Lambda函数,这为处理集合数据提供了极大的便利。例如,可以通过Lambda表达式对列表中的元素进行过滤、映射或聚合操作。 - **投影与选择**:OGNL提供了强大的集合操作功能,支持对集合中的元素进行投影(即提特定属性)和选择(即根据条件筛选元素)。例如,可以通过`list.{? #this.age > 18}`来筛选出年龄大于18的所有用户。 - **上下文管理**:OGNL支持多级上下文环境,这意味着开发者可以在不同的作用域中定义变量和方法,并根据需要切换上下文。这种机制非常适合处理复杂的业务逻辑,尤其是在需要跨多个对象或模块进行数据交互的情况下。 ### 注意事项 尽管OGNL表达式功能强大且用途广泛,但在实际使用过程中仍需注意以下几点: - **性能优化**:由于OGNL表达式的解析和执行过程可能会带来一定的性能开销,因此在高频调用或性能敏感的场景下应谨慎使用。可以通过缓存已解析的表达式或减少不必要的表达式调用次数来优化性能。 - **安全性问题**:OGNL表达式的动态性也可能成为潜在的安全隐患。特别是在接受用户输入并将其作为表达式执行的情况下,必须严格验证和过滤输入内容,防止恶意攻击(如代码注入)。建议在涉及用户输入的场景中,采用白名单机制或限制表达式的执行权限。 - **调试难度**:由于OGNL表达式通常隐藏在框架内部或配置文件中,其执行过程不易跟踪和调试。为了降低维护成本,建议在关键路径上添加日志记录,并尽量保持表达式的简洁性和可读性。 ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值