`
jindw
  • 浏览: 500765 次
  • 性别: 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程序解释一下嘛?

相关推荐

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

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

    JAVA上百实例源码以及开源项目

    百度云盘分享 简介 笔者当初为了学习JAVA,收集了很多经典源码,源码难易程度分为初级、中级、高级等,详情看源码列表,需要的可以直接下载! 这些源码反映了那时那景笔者对未来的盲目,对代码的热情、执着,对...

    JAVA上百实例源码以及开源项目源代码

    简介 笔者当初为了学习JAVA,收集了很多经典源码,源码难易程度分为初级、中级、高级等,详情看源码列表,需要的可以直接下载! 这些源码反映了那时那景笔者对未来的盲目,对代码的热情、执着,对IT的憧憬、向往!...

    word源码java-JSP:JSP

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

    java开源包1

    Beetl,是Bee Template Language的缩写,它绝不是简单的另外一种模板引擎,而是新一代的模板引擎,它功能强大,性能良好,秒杀当前流行的模板引擎。而且还易学易用。 Java的COM桥 JCom JCom (Java-COM Bridge) 可以...

    java开源包11

    Beetl,是Bee Template Language的缩写,它绝不是简单的另外一种模板引擎,而是新一代的模板引擎,它功能强大,性能良好,秒杀当前流行的模板引擎。而且还易学易用。 Java的COM桥 JCom JCom (Java-COM Bridge) 可以...

    java开源包2

    Beetl,是Bee Template Language的缩写,它绝不是简单的另外一种模板引擎,而是新一代的模板引擎,它功能强大,性能良好,秒杀当前流行的模板引擎。而且还易学易用。 Java的COM桥 JCom JCom (Java-COM Bridge) 可以...

    java开源包3

    Beetl,是Bee Template Language的缩写,它绝不是简单的另外一种模板引擎,而是新一代的模板引擎,它功能强大,性能良好,秒杀当前流行的模板引擎。而且还易学易用。 Java的COM桥 JCom JCom (Java-COM Bridge) 可以...

    java开源包6

    Beetl,是Bee Template Language的缩写,它绝不是简单的另外一种模板引擎,而是新一代的模板引擎,它功能强大,性能良好,秒杀当前流行的模板引擎。而且还易学易用。 Java的COM桥 JCom JCom (Java-COM Bridge) 可以...

    java开源包5

    Beetl,是Bee Template Language的缩写,它绝不是简单的另外一种模板引擎,而是新一代的模板引擎,它功能强大,性能良好,秒杀当前流行的模板引擎。而且还易学易用。 Java的COM桥 JCom JCom (Java-COM Bridge) 可以...

    java开源包10

    Beetl,是Bee Template Language的缩写,它绝不是简单的另外一种模板引擎,而是新一代的模板引擎,它功能强大,性能良好,秒杀当前流行的模板引擎。而且还易学易用。 Java的COM桥 JCom JCom (Java-COM Bridge) 可以...

    java开源包4

    Beetl,是Bee Template Language的缩写,它绝不是简单的另外一种模板引擎,而是新一代的模板引擎,它功能强大,性能良好,秒杀当前流行的模板引擎。而且还易学易用。 Java的COM桥 JCom JCom (Java-COM Bridge) 可以...

    java开源包8

    Beetl,是Bee Template Language的缩写,它绝不是简单的另外一种模板引擎,而是新一代的模板引擎,它功能强大,性能良好,秒杀当前流行的模板引擎。而且还易学易用。 Java的COM桥 JCom JCom (Java-COM Bridge) 可以...

    java开源包7

    Beetl,是Bee Template Language的缩写,它绝不是简单的另外一种模板引擎,而是新一代的模板引擎,它功能强大,性能良好,秒杀当前流行的模板引擎。而且还易学易用。 Java的COM桥 JCom JCom (Java-COM Bridge) 可以...

    java开源包9

    Beetl,是Bee Template Language的缩写,它绝不是简单的另外一种模板引擎,而是新一代的模板引擎,它功能强大,性能良好,秒杀当前流行的模板引擎。而且还易学易用。 Java的COM桥 JCom JCom (Java-COM Bridge) 可以...

    java开源包101

    Beetl,是Bee Template Language的缩写,它绝不是简单的另外一种模板引擎,而是新一代的模板引擎,它功能强大,性能良好,秒杀当前流行的模板引擎。而且还易学易用。 Java的COM桥 JCom JCom (Java-COM Bridge) 可以...

    Java资源包01

    Beetl,是Bee Template Language的缩写,它绝不是简单的另外一种模板引擎,而是新一代的模板引擎,它功能强大,性能良好,秒杀当前流行的模板引擎。而且还易学易用。 Java的COM桥 JCom JCom (Java-COM Bridge) 可以...

    Java及大数据学习路线.pdf

    2.1JavaSE Java基础 Java8新特性 数据库MySQL与SQL语⾔ JDBC 2.2JavaEE核⼼ HTML、CSS、JS、XML Tomcat服务器、HTTP协议、JSP、Servlet组件 EL表达式、会话控制、⽂件的上传下载 Filter组件、Listener组件、异步传输...

Global site tag (gtag.js) - Google Analytics