Ognl 语法基础教程

简介: 本文将力求用最简单的语言和实例,介绍一下 OGNL 的语法规则,文章主要内容参考自官方文档commons.apache.org/proper/comm…本篇主要是语法介绍篇,实战放在一下篇因为本篇文章将是后 quick-fix 2.0 版本支持 ognl 的前导篇,先提前放出

本文将力求用最简单的语言和实例,介绍一下 OGNL 的语法规则,文章主要内容参考自官方文档commons.apache.org/proper/comm…


  • 本篇主要是语法介绍篇,实战放在一下篇
  • 因为本篇文章将是后 quick-fix 2.0 版本支持 ognl 的前导篇,先提前放出


1. 前言



ognl,全称 Object Graphic Navigation Language(对象图导航语言),根据约定的一些简单的规则,组装一个利于阅读、可执行的表达式语句


如下面是一个典型的表达式


"name".toCharArray()[0].numericValue.toString()
复制代码


即便完全不懂 ognl,单纯的以 java 的基础知识就可以看懂,而这就是 ognl 的魅力所在 (学习一点点东西,就可以马上入手)


2. 对象定位



说明,这一小节的内容为我个人为了方便理解而分类的,并不官方


我们知道在 java 中,一切都是对象,所以我们的 ognl 表达式必然是着手于某一个对象的,通常在 ognl 中,可以将待执行目标对象划分为三类


  • 简单对象:(如基本数据类型,String)
  • 非简单对象:(非简单对象,实例访问)
  • 静态对象:(静态类)


在 gonl 的语法中,上面三种 case,根据不同的开头来标记


静态对象


简单来说就是我想访问静态类的某个方法(或者静态类的成员)

@java.lang.Math
复制代码


语法规则为根据@开始,后面接上完整的类名


一个实例 case 如下,相当于 java 代码中直接调用Math.max(10, 20)


@java.lang.Math@max(10, 20)
复制代码


非简单对象


访问一个普通对象的成员 or 方法


#demo
复制代码


语法规则为根据#开头,后面为对象名(说明,这个对象需要在 Ognl 的上下文中,且可以根据对象名可以唯一定位)


简单对象


即基本类型的对象访问,不加任何前缀,直接使用即可,如下


// 字符串的长度
"name".length()
// 数字计算
1+2
// boolean
true
复制代码


3. 方法调用



执行目标对象的某个方法,规则如下


// 非基本对象的方法访问,#开头,对象与方法之间用.连接
#obj.method( 参数 )
// 静态对象的方法访问,@开头,对象与方法之间用@连接
@xxx@method( 参数 )
// 基本对象的方法访问,和非基本对象方法方式一致
"name".length()
复制代码


4. 成员访问



访问目标对象的成员,规则如下

// 非基本对象的成员访问,#开头,对象与成员之间用.连接
#obj.field
// 静态对象的成员访问,@开头,对象与成员之间用@连接
@xxx@field
// 基本对象的成员访问,和非基本对象成员方式一致
"name".hash
复制代码


5. 集合



ognl 针对常用的集合进行了特殊的支持


List


通过{}创建列表,通过[]来访问对象下标的元素

下面表示创建一个列表,有三个元素: 1,2,3; 获取列表中下标为 2 的元素

{1, 2, 3}[2]
复制代码


Arrays


数组,可以结合 new 来使用

new int[] {1,2,3}
复制代码


Map


#{k:v, k:v} 方式来创建 map

下面的语句,表示创建一个 map,并获取其中 key 为 name 的元素

#{ "name" : "一灰灰Blog", "age" :  18}["name"]
复制代码


6. 表达式语句



前面是一些简单的,基本的成员访问,方法调用,除此之外还存在更牛逼的用法,支持表达式的执行


成员赋值

#demo.name = "一灰灰blog"
复制代码


表达式计算

500 + 20 - 30 * 3
复制代码


三目运算符

"name".length() % 2 == 0 ? "偶数长度" : "奇数长度"
复制代码


集合支持


针对集合做了一些简化,方便调用

// in 语句,判断列表中是否包含
"name" in {"name", "hello"}
// 遍历集合,获取所有的偶数
{1,2,3,4,5,6}.{? #this % 2 == 0}
// 遍历集合,获取第一个满足条件的元素
{1,2,3,4,5,6}.{^ #this % 2 == 0}
// 遍历集合,获取最后一个满足条件的元素
{1,2,3,4,5,6}.{$ #this % 2 == 0}
复制代码


对象创建


可以直接通过 new 来创建一个对象,当我们需要执行的目标方法的参数为非基本类型时,可能会非常好用


// new + 完整的类名
new java.lang.String("hello world")
复制代码


链式语句


什么是链式语句呢?


有点类似设计模式中的 Builder 模式,我要执行一串的操作,最后获取目标

定义规则如下,圆括号包裹起来,中间用逗号分隔,依次执行,最后一个为需要返回的目标

(step1, step2,..., result)
复制代码


结合上面的对象创建,可以实现非常强大的功能


package git.hui;
class User {
  public String name;
  public Integer age;
}
复制代码


直接创建一个可用的 User 对象,下面执行完毕之后,直接获取一个属性被初始化后的 User 对象


(#user=new git.hui.User(),  #user.name="一灰灰Blog", #user.age=18, #user)
复制代码


lambda 表达式


这个有点高端了,首先是定义 lambda 表达式,然后借助前面的链式方式调用,下面是一个阶乘的 case


#fact = :[#this<=1? 1 : #this*#fact(#this-1)], #fact(3)



相关文章
|
6月前
|
存储 Java
从零开始学习 Java:简单易懂的入门指南之Map集合(二十三)
从零开始学习 Java:简单易懂的入门指南之Map集合(二十三)
|
6月前
|
存储 Java
从零开始学习 Java:简单易懂的入门指南之可变参数及Collections类(二十五)
从零开始学习 Java:简单易懂的入门指南之可变参数及Collections类(二十五)
|
Java
JavaWeb第十章课后题 EL表达式
JavaWeb第十章课后题 EL表达式
196 0
|
存储 安全 编译器
C++入门语法基础
C++入门语法基础
82 0
C++入门语法基础
|
存储 安全 C语言
C++ 语法基础(三)(一)
C++ 语法基础(三)(一)
C++ 语法基础(三)(一)
|
存储 程序员 C++
C++ 语法基础(四)(一)
C++ 语法基础(四)(一)
C++ 语法基础(四)(一)
|
编译器 C++
C++ 语法基础(二)(三)
C++ 语法基础(二)(三)
C++ 语法基础(二)(三)
|
编译器 C++
C++ 语法基础(二)(二)
C++ 语法基础(二)(二)
C++ 语法基础(二)(二)
|
存储 编译器 C++
C++ 语法基础(三)(二)
C++ 语法基础(三)(二)
C++ 语法基础(三)(二)
下一篇
无影云桌面