`
jindw
  • 浏览: 510096 次
  • 性别: Icon_minigender_1
  • 来自: 初到北京
社区版块
存档分类
最新评论

表达式引擎JSEL介绍

    博客分类:
  • Java
阅读更多
表达式引擎的定义这里我就不说了,先假设大家都知道^_^


JSEL之前也出现过不少其他类似产品,包括老牌的Ognl(老到网站都找不到了),新来的MVEL,还有我们国产的Aviator,IKExpression

居然有了这么多可用的实现,那么JSEL的亮点又在那里呢?

基于ECMA262标准的子集
JSEL是一个兼容 JavaScript 运算规则的简单的表达式解释引擎。
支持ECMA标准的运算符、函数库并内置了JSON支持。
基本语法是JavaScript的一个子集,基本语法有良好群众基础。

一个可以完全自定义的表达式系统
全新运算符支持,运算符别名,优先级控制,内置对象设置,等等,一切皆有可能。你完全可以在JSEL基础上DIY一套适合你自己的表达式系统。
详情可参考:http://code.google.com/p/lite/wiki/JSELExtension

执行效率远高于同类
其实,本人在开发过程中,并没有太注重效率,甚至为保持与JavaScript的兼容性,我不得不采用影响性能的设计。
然而,发布出来后,一做性能测试,反成了意外的惊喜。
我将另外撰文列出性能对比的详细数据,精彩稍后继续,不要离开^_^

内置功能强大的JSON解释支持
因为JSEL本身是基于JavaScript规则的,JSON本身就是JavaScript功能的子集,那么JSEL自然也就是一个天然的JSON工具,此外,表达式的编译,本身就继承了JSON解析的功能,而且,我们也吧JSON支持的功能提出为独立的模块,相比官方的JSON解析,JSEL的JSON功能更简单,更有独到的优点【稍后继续补充】

这里也有少许介绍:http://code.google.com/p/lite/wiki/JSON
补充:常见表达式引擎执行性能比较:http://www.iteye.com/topic/732354


不仅是一个表达式
此外JSEL还提供了一些常用的工具支持,如命令行解析器,这是一个在表达式基础上建立起来的功能强大的命令行分析程序,如果你想编写一些基于命令行的工具程序,那么JSEL绝对是您最棒的助手。

该工具的基本用法简介:http://code.google.com/p/lite/wiki/CPEL

背后是一个空前强大的模板系统
JSEL并不是一个为了表达式而编写的表达式引擎,他本来只是Lite模板的一个基本功能,目前Lite模板系统正在做全面重构。这里就先留个悬念吧。以后你会知道的^_^


------------------------------
JSEL基于LGPL开源协议发布,(LiteRT-yyMMdd.jar,与Lite模板运行环境一起打包发布,不足100k),你可以从如下地址下载,并将其功能集成到你的系统中。
http://code.google.com/p/lite/downloads/list
分享到:
评论
11 楼 luo2pei4321 2011-03-11  
MVEL的官方例子里面好像只支持Integer和String两种类型的参数.想问下你用MVEL测试上面运算式时是怎么通过的.

测试代码:
Map<String, Double> test = new HashMap<String, Double>();
test.put("a", new Double(9.3));
test.put("b", new Double(3.7));
String result = (String)MVEL.eval("a * b", test);

输出的异常:
Exception in thread "main" java.lang.ClassCastException: java.lang.Double
at test.Test.main(Test.java:19)
10 楼 jindw 2010-08-15  
olivechinese 写道
周未用了下
JSEL
发现JSEL对 纯 数学运算 在同类产品中,效率是最高的,
但是在 对象运算中如,  'A' == 'A' || 'B' == 'B' && 'ABCD' == ABCD &&  'A' == 'A' 或其他自定义对象中,效率要比JEXL要低,
希望能改进这方面的算法


非常感谢你的关注,更重要的是,你这个测试让我发现了一个bug,运算符优先级的问题: 运算符二级优先级判断错误 

这个问题已经在今天中午发布的2.0A4中修复。

修复这个问题后,我这边的测试数据是:
---------------------
Source:'A' == 'A' || 'B' == 'B' && 'ABCD' == t &&  'A' == 'A' (result=true)
Labels:		MVEL      		Ognl      		Aviator   		JXEL      		JSEL      
Times:		3.019352  		0.985064  		11.102609 		11.200559 		0.531242  
Scale:		5.683572  		1.854266  		20.899343 		21.083723 		1.0       
---------------------
Source:1000+100.0*99-(600-3*15)%(((68-9)-3)*2-100)+10000%7*71(result=11181.0)
Labels:		MVEL      		Ognl      		Aviator   		JXEL      		JSEL      
Times:		0.307111  		0.172375  		10.650497 		44.61275  		0.507288  
Scale:		1.7816447 		1.0       		61.786785 		258.8122  		2.9429326 
---------------------
测试结果不一致:MVEL=-7,Ognl=1
测试结果类型不一致:result=1,Ognl=class java.lang.Integer,Aviator=class java.lang.Long
测试结果类型不一致:result=1,Aviator=class java.lang.Long,JXEL=class java.lang.Integer
测试结果类型不一致:result=1,JXEL=class java.lang.Integer,JSEL=class java.lang.Long
Source:6.7-100>39.6 ? 5==5? 4+5:6-1 : !(100%3-39.0<27) ? 8*2-199: 100%3(result=1)
Labels:		MVEL      		Ognl      		Aviator   		JXEL      		JSEL      
Times:		5.123787  		0.164249  		4.438563  		12.610787 		0.110355  
Scale:		46.43004  		1.4883693 		40.220768 		114.27472 		1.0       
---------------------
表达式测试异常:Ognljavassist.CannotCompileException: [source error] ) is missing
测试结果不一致:MVEL=true,Ognl=null
测试结果不一致:Ognl=null,Aviator=true
Source:i * pi + (d * b - 199) / (1 - d * pi) - (2 + 100 - i / pi) % 99 ==i * pi + (d * b - 199) / (1 - d * pi) - (2 + 100 - i / pi) % 99(result=true)
Labels:		MVEL      		Ognl      		Aviator   		JXEL      		JSEL      
Times:		234.21127 		2147.4836 		61.84004  		14.983838 		8.319792  
Scale:		28.151098 		258.11746 		7.432883  		1.8009871 		1.0       
---------------------
测试结果不一致:MVEL=314.0000104904175,Ognl=314.0
测试结果不一致:Ognl=314.0,Aviator=314.0000104904175
测试结果不一致:Aviator=314.0000104904175,JXEL=314.0
测试结果类型不一致:result=314.0,JXEL=class java.lang.Double,JSEL=class java.lang.Float
Source:i * pi(result=314.0)
Labels:		MVEL      		Ognl      		Aviator   		JXEL      		JSEL      
Times:		5.42876   		0.374265  		2.375617  		0.92347   		0.844769  
Scale:		14.505123 		1.0       		6.3474197 		2.4674227 		2.2571414 
---------------------
测试结果类型不一致:result=1,Ognl=class java.lang.Integer,Aviator=class java.lang.Long
测试结果类型不一致:result=1,Aviator=class java.lang.Long,JXEL=class java.lang.Integer
测试结果类型不一致:result=1,JXEL=class java.lang.Integer,JSEL=class java.lang.Long
Source:1(result=1)
Labels:		MVEL      		Ognl      		Aviator   		JXEL      		JSEL      
Times:		0.122759  		0.14885   		1.7152    		0.039351  		0.053039  
Scale:		3.1195903 		3.782623  		43.587204 		1.0       		1.3478438 
---------------------
表达式测试异常:Aviatorcom.googlecode.aviator.exception.ExpressionRuntimeException: Execute expression error
测试结果不一致:Ognl=4,Aviator=null
测试结果不一致:Aviator=null,JXEL=4
Source:thiz.add(1,3)(result=4)
Labels:		MVEL      		Ognl      		Aviator   		JXEL      		JSEL      
Times:		43.03785  		1.216466  		2147.4836 		16.89494  		13.938891 
Scale:		35.37941  		1.0       		1765.3462 		13.888543 		11.458512 
9 楼 olivechinese 2010-08-14  
周未用了下
JSEL
发现JSEL对 纯 数学运算 在同类产品中,效率是最高的,
但是在 对象运算中如,  'A' == 'A' || 'B' == 'B' && 'ABCD' == ABCD &&  'A' == 'A' 或其他自定义对象中,效率要比JEXL要低,
希望能改进这方面的算法
8 楼 binlaniua 2010-08-09  
强大... 强势关注
7 楼 jindw 2010-08-09  
downpour 写道
jindw 写道
downpour 写道
其实我所关心的是,你的这个表达式引擎是否能像OGNL一样做到双向的转化关系,并且包含了类型转换。这个双向的转化关系包括:

1. 字符串 + 表达式 =》Java对象(其中包含了从字符串到Java类型的转换)

2. Java对象 + 表达式 =》字符串表现(其中包含了从Java类型到字符串不同表现形式的转换)

OGNL在这两点上做的很好,只是目前OGNL存在的问题主要在于效率和API的灵活性。

我希望能够看到一个效率远远大于OGNL,但是又不丧失OGNL功能的表达式引擎,最好在API级别,又比较友好,不像OGNL那样有如此多的全局设置。



OGNL确实很强大,不过API的设计也确实糟糕透了。
JSEL的目标并不是为了复制OGNL的功能,有些功能是否应该添加还是要慎重考虑的。
做的太多了,没准就会接近OGNL的复杂了。

仍外,我们也可以考虑在JSEL基础上衍生出一些子项目,用来满足更独立的功能。
这样,JSEL的设计就可以多考虑一些可扩展性,不必内置太多的功能,以免过于复杂。

关于这里说的双向转换。
1. 字符串 + 表达式 =》Java对象(其中包含了从字符串到Java类型的转换)
这点,JSEL做的是:
变量表+表达式=》Java对象。当能,这里也内置了部分JSON字面量=》Java对象的功能。
2. Java对象 + 表达式 =》字符串表现(其中包含了从Java类型到字符串不同表现形式的转换)
这里,JSEL并没有提供类似OGNL的getAsText的方法,不过JSEL可以自定义对象的成员方法,包括toString,从架构上是可以扩展的,但是,这些功能并没有内置到系统中,如果要实现,还是应该自行封装的。



如果你的表达式引擎的效率高,并且能满足我上面说的2点,我倒是很乐意把Struts2的OGNL依赖替换掉,使用你的引擎。

待我有时间的时候好好研究一下你的这个表达式引擎再过来讨论。

JSEL带有设值功能,我也用它来做国类似webwork的servlet 参数=》JavaBean属性的自动转换,如果用它来代替Struts2的OGNL应该也是可行的,只是我工作中不涉及到这块,所以目前还没有尝试。

如果你有兴趣试试的化,欢迎随时交流。
6 楼 downpour 2010-08-09  
jindw 写道
downpour 写道
其实我所关心的是,你的这个表达式引擎是否能像OGNL一样做到双向的转化关系,并且包含了类型转换。这个双向的转化关系包括:

1. 字符串 + 表达式 =》Java对象(其中包含了从字符串到Java类型的转换)

2. Java对象 + 表达式 =》字符串表现(其中包含了从Java类型到字符串不同表现形式的转换)

OGNL在这两点上做的很好,只是目前OGNL存在的问题主要在于效率和API的灵活性。

我希望能够看到一个效率远远大于OGNL,但是又不丧失OGNL功能的表达式引擎,最好在API级别,又比较友好,不像OGNL那样有如此多的全局设置。



OGNL确实很强大,不过API的设计也确实糟糕透了。
JSEL的目标并不是为了复制OGNL的功能,有些功能是否应该添加还是要慎重考虑的。
做的太多了,没准就会接近OGNL的复杂了。

仍外,我们也可以考虑在JSEL基础上衍生出一些子项目,用来满足更独立的功能。
这样,JSEL的设计就可以多考虑一些可扩展性,不必内置太多的功能,以免过于复杂。

关于这里说的双向转换。
1. 字符串 + 表达式 =》Java对象(其中包含了从字符串到Java类型的转换)
这点,JSEL做的是:
变量表+表达式=》Java对象。当能,这里也内置了部分JSON字面量=》Java对象的功能。
2. Java对象 + 表达式 =》字符串表现(其中包含了从Java类型到字符串不同表现形式的转换)
这里,JSEL并没有提供类似OGNL的getAsText的方法,不过JSEL可以自定义对象的成员方法,包括toString,从架构上是可以扩展的,但是,这些功能并没有内置到系统中,如果要实现,还是应该自行封装的。



如果你的表达式引擎的效率高,并且能满足我上面说的2点,我倒是很乐意把Struts2的OGNL依赖替换掉,使用你的引擎。

待我有时间的时候好好研究一下你的这个表达式引擎再过来讨论。
5 楼 jindw 2010-08-09  
downpour 写道
其实我所关心的是,你的这个表达式引擎是否能像OGNL一样做到双向的转化关系,并且包含了类型转换。这个双向的转化关系包括:

1. 字符串 + 表达式 =》Java对象(其中包含了从字符串到Java类型的转换)

2. Java对象 + 表达式 =》字符串表现(其中包含了从Java类型到字符串不同表现形式的转换)

OGNL在这两点上做的很好,只是目前OGNL存在的问题主要在于效率和API的灵活性。

我希望能够看到一个效率远远大于OGNL,但是又不丧失OGNL功能的表达式引擎,最好在API级别,又比较友好,不像OGNL那样有如此多的全局设置。



OGNL确实很强大,不过API的设计也确实糟糕透了。
JSEL的目标并不是为了复制OGNL的功能,有些功能是否应该添加还是要慎重考虑的。
做的太多了,没准就会接近OGNL的复杂了。

仍外,我们也可以考虑在JSEL基础上衍生出一些子项目,用来满足更独立的功能。
这样,JSEL的设计就可以多考虑一些可扩展性,不必内置太多的功能,以免过于复杂。

关于这里说的双向转换。
1. 字符串 + 表达式 =》Java对象(其中包含了从字符串到Java类型的转换)
这点,JSEL做的是:
变量表+表达式=》Java对象。当能,这里也内置了部分JSON字面量=》Java对象的功能。
2. Java对象 + 表达式 =》字符串表现(其中包含了从Java类型到字符串不同表现形式的转换)
这里,JSEL并没有提供类似OGNL的getAsText的方法,不过JSEL可以自定义对象的成员方法,包括toString,从架构上是可以扩展的,但是,这些功能并没有内置到系统中,如果要实现,还是应该自行封装的。

4 楼 downpour 2010-08-09  
其实我所关心的是,你的这个表达式引擎是否能像OGNL一样做到双向的转化关系,并且包含了类型转换。这个双向的转化关系包括:

1. 字符串 + 表达式 =》Java对象(其中包含了从字符串到Java类型的转换)

2. Java对象 + 表达式 =》字符串表现(其中包含了从Java类型到字符串不同表现形式的转换)

OGNL在这两点上做的很好,只是目前OGNL存在的问题主要在于效率和API的灵活性。

我希望能够看到一个效率远远大于OGNL,但是又不丧失OGNL功能的表达式引擎,最好在API级别,又比较友好,不像OGNL那样有如此多的全局设置。

3 楼 jindw 2010-08-09  
downpour 写道
关心一下你是如何实现类型转换的。

举例来说,我在页面上有个值,是日期形式表示:2010-08-05,我如何在Java端获取到一个Date对象?能写段Sample程序解释一下嘛?


下个周末吧日期支持加上去,这确实是我的疏忽。

目前的想法是,遇到Date对象,就按ISO的日期规范( YYYY-MM-DDThh:mm:ss.sTZD (eg 1997-07-16T19:20:30.45+01:00)
)直接系列化成字符串,解码的时候,如果遇到目标类型是日期,也先尝试用ISO规范解析。
大家如果有什么想法,欢迎讨论^_^
2 楼 jindw 2010-08-09  
downpour 写道
关心一下你是如何实现类型转换的。

举例来说,我在页面上有个值,是日期形式表示:2010-08-05,我如何在Java端获取到一个Date对象?能写段Sample程序解释一下嘛?



日期类型还没有特别的支持,现在只能当普通JavaBean处理。
因为JSON标准中,并没有日期的定义,所以,这个确实是个麻烦事,特别是序列化的时候,不知道该如何实现,才能既不违反标准,又能相对合理。


java.util.Date实例:
public class JSONDateTest {
	private Date utilDate = new Date(System.currentTimeMillis());
	public Date getUtilDate() {
		return utilDate;
	}
	public void setUtilDate(Date utilDate) {
		this.utilDate = utilDate;
	}
	@Test
	public void test(){
		JSONDecoder decoder = new JSONDecoder(true);
		String result = JSONEncoder.encode(this);
		System.out.println(result);
		JSONDateTest object = decoder.decode(result, this.getClass());
		System.out.println(JSONEncoder.encode(object));
	}

}


{"utilDate":{"date":9,"day":1,"hours":11,"minutes":33,"month":7,"seconds":48,"time":1281324828943,"timezoneOffset":-480,"year":110}}
{"utilDate":{"date":9,"day":1,"hours":11,"minutes":33,"month":7,"seconds":48,"time":1281324828943,"timezoneOffset":-480,"year":110}}

如果是java.sql.Date.因为他的getHours方法,会抛出异常,导致编码的时候会丢失信息,而解码的时候,因为没有默认构造器,所以,也无法正确解码。

这确实是一非常值得改进的地方,下一个版本改进吧,多谢提醒:)
1 楼 downpour 2010-08-09  
关心一下你是如何实现类型转换的。

举例来说,我在页面上有个值,是日期形式表示:2010-08-05,我如何在Java端获取到一个Date对象?能写段Sample程序解释一下嘛?

相关推荐

    js中如何引用EL表达式.txt

    在这个例子中,`${msgs.addFullName}`是一个EL表达式,它会被JSP引擎解析并计算出一个值,然后通过`&lt;%= %&gt;`插入到JS代码中,成为`var addFullName`变量的值。 #### 方法二:使用数据属性 另一种方法是利用HTML5的...

    工作流程图-规则引擎图(javascript)

    4. **可扩展性**:JavaScript库如D3.js提供了丰富的功能,可以轻松地扩展工作流程图和规则引擎图的功能,如动画效果、实时更新等。 总的来说,工作流程图和规则引擎图是业务逻辑和流程管理的重要工具。利用...

    jsp页面中EL表达式被当成字符串处理不显示值问题的解决方法

    `isELIgnored="true"`意味着JSP引擎会忽略EL表达式,将其视为普通字符串处理,而`isELIgnored="false"`则启用EL表达式解析。 在JavaEE4中,默认情况下`isELIgnored`是设为`false`的,这意味着EL表达式会被解析。但...

    Java表达式攻防下的黑魔法-release

    Java表达式攻防中的黑魔法(Black Magic)主要集中在Java表达式语言(EL)、Spring表达式语言(SpEL)以及对象图导航语言(OGNL)等领域。 #### 关键概念解析 1. **Java表达式语言(EL)**: - **定义**:EL是一...

    正则表达式系统教程中文版.zip

    4. **正则表达式引擎** - **DFA(确定有限状态自动机)**:快速但可能无法找到所有匹配,通常用于简单的模式。 - **NFA(非确定有限状态自动机)**:更灵活,能匹配复杂模式,但可能较慢。 5. **实践案例** - **...

    基于规则引擎liteflow, 使用前端架构LogicFlow 开发的前端配置页面 通过页面配置生成json,交给后端生成EL

    将JSON数据提交给后端后,后端可以解析这些数据,并利用Liteflow规则引擎生成相应的EL(Expression Language)表达式。 EL表达式是一种简化版的脚本语言,常用于Web应用中,用来动态计算和访问JavaBeans属性。在...

    新版搜索引擎获取搜索关键词

    本文将详细介绍一种新版轻量化搜索引擎关键词获取技术,该技术不仅能够有效获取百度等主流搜索引擎的关键词,还特别强调了对百度移动端的支持,以及对PC端非竞价排名情况下的关键词获取限制。 #### 二、技术背景与...

    获取搜索引擎关键词

    本文将详细介绍一个JavaScript脚本,该脚本能够实现从用户来源URL中提取搜索引擎关键词的功能。 #### 核心知识点解析 ##### 1. 函数 `getDomainQuery(url)` 此函数用于从给定的URL中提取域名及其后的查询字符串。...

    ExtJS Jetty启动报错 tag

    这表明在解析JSP标签时,Jasper引擎无法正确处理该EL(Expression Language)表达式。 EL是JSP 2.0引入的一种轻量级脚本语言,用于在JSP页面中访问JavaBeans或其他数据源。表达式`${empty(extLocation)?"js/ext-2.0...

    基于Bpmn.js、Vue 2.x 和ElementUI的流程编辑器(前端部分),支持监听器,扩展属性,表单等配置,可自由扩展

    一个基于 bpmn.js,Vue 2.x 和 ElementUI 开发的 BPMN 2.0 流程设计器(网页版),您可以使用它在浏览器上查看和编辑符合 BPMN 2.0 规范的流程文件。支持监听器,扩展属性,表单等配置,可自由扩展。项目内置 ...

    java+web项目实战大全源码搜索引擎源码整理

    开发者需要掌握Servlet生命周期、请求响应机制以及JSP中的EL表达式和JSTL标签库。 3. **MVC设计模式**:搜索引擎项目可能采用Model-View-Controller架构,将业务逻辑、数据模型和用户界面分离,提高代码可维护性和...

    node-jsp:一个非常简单的JSP解析器和视图引擎

    解析器可能需要处理 JSP 标签、表达式语言(EL)、脚本元素、指令等关键组成部分。 视图引擎则负责将解析后的 JSP 内容渲染成 HTML 输出。它需要处理 JSP 中的控制结构(如 if-else、foreach)和动态内容,根据数据...

    jsp页面使用${}不起作用的解决方法

    在JSP中,`${}`表达式通常被称为EL(Expression Language),它允许开发者方便地访问JavaBean或其他数据源中的属性。然而,有时候在尝试使用`${}`时可能会遇到它们不起作用的情况,这通常是由于缺少了必要的库或者...

    解决vue与node模版引擎的渲染标记{{}}(双花括号)冲突问题

    本文将深入探讨如何解决Vue.js与Node.js模版引擎之间的模板语法冲突,特别是如何处理两者都使用的双花括号`{{ }}`作为模板表达式的界定符号这一具体场景。 #### Vue.js 模板语法简介 Vue.js 是一种轻量级的前端...

    word源码java-JSP:JSP

    code,表达式语言(EL),jst1标签 3,如何工作及其特点? 1)jsp其实就是一个servlet 2)jsp的运行需要服务器的支持 服务器中的jsp引擎可以帮我们去运行页面.引擎就是别人写好的java code 4)jsp在运行之前要经过几个步骤:...

    SpringMvc+JS实现基于session的国际化

    在JSP或HTML页面上,通过EL表达式或Thymeleaf等模板引擎引用这些翻译文本,从而实现页面内容的国际化。 总之,Spring MVC结合JavaScript实现基于Session的国际化是一种常见的实践方法,它允许Web应用轻松地支持多...

    thymeleaf-3.0.11.RELEASE-英文手册.pdf

    Thymeleaf的核心特性之一是其表达式语言(EL),它允许在模板中嵌入变量、条件语句、循环等逻辑。例如,`th:text="${variable}"` 将根据Java后台提供的数据替换为对应的值。此外,Thymeleaf支持条件属性,如`th:if` ...

    Activiti学习文档(二)之画流程图并部署流程

    同时,Activiti还提供了丰富的API和表达式语言(EL),使得在流程中进行动态计算和决策成为可能。 总结来说,“Activiti学习文档(二)之画流程图并部署流程”会带你走过从设计到实施一个完整流程的整个过程,包括...

    thmeleaf项目实例

    2. **强大的表达式语言(EL)**:Thymeleaf的表达式语言允许你轻松地访问模型对象、执行运算和控制流。例如,`th:text="${user.name}"` 将在页面上显示用户对象的name属性。 3. **多模式支持**:Thymeleaf支持多种...

Global site tag (gtag.js) - Google Analytics