QLExpress使用问题
来源:互联网 发布:linux c 多线程编程 编辑:程序博客网 时间:2024/06/05 11:01
QLExpress在Java&Scala中使用问题
需求: 简单的规则引擎(支持四则运算),scala 下运行。先尝试在java下测试demo。
资料
artifact :<dependency>
<groupId>com.taobao.util</groupId>
<artifactId>taobao-express</artifactId>
<version>3.0.17</version>
</dependency>
github : https://github.com/alibaba/QLExpressjar使用问题
官方仓库 http://maven.aliyun.com/nexus/content/repositories/public 下找不到的该jar;
在项目提供的mvn地址 http://mvnrepo.alibaba-inc.com/mvn 也无法打开。
下面就需要本地去尝试做mvn deploy。
1. 在github下载源码后解压到IDEA,
2. mvn compile 可以编译成功
mvn package 错误,BUILD FAILURE。
[ERROR] /C:/Users/.../QLExpress-master/src/test/java/com/ql/util/express/test/AClassDefineSingle.java:[12,40] unmappable character for encoding GBK
很明显由于IDE设置的encoding : utf-8, 而该项目应该是gbk的。
下一步去修改项目的编码-> GBK。
3.重新设置GBK(注意这里项目中文件可能存在多种编码)后, 会发现很多单元测试异常,依然无法通过打包。
4.放弃完整打包, 即只打包源码, 跳过项目的test阶段,需要加上-DskipTests
mvn package -Dmaven.test.skip=true
最后得到这个jar,可以选择丢在本地仓库, 或者用deploy丢到nuxus的远程库上面去, 在使用maven去引用它!
5. 测试:
public class Test { public static void main(String[] args) throws Exception{ String express = "10 * 10 + 1 + 2 * 3 + 5 * 2"; ExpressRunner runner = new ExpressRunner(false,true); Object r = runner.execute(express,null, null, true,true); System.out.println("表达式计算:" + express + " = " + r); }}
附scala的运行结果:
scalaVersion := "2.10.4"sbtVersion := "1.0.3"
因为我的qlexpress丢在了公司的库上面, 所以必须申明一下:
libraryDependencies += "com.taobao.util" % "taobao-express" % "3.1.7"resolvers += " Maven Repository [nexus] " at "http://192.168.9.200:8002/nexus/content/groups/public/"
demo :
import com.ql.util.express.ExpressRunner/** * * * @author michael * @version 1.0 Created on 2017/12/19 12:11 */object QlDemo { def main(args: Array[String]): Unit = { val express = "10 * 10 + 1 + 2 * 3 + 5 * 2" val runner = new ExpressRunner(false, true) val r = runner.execute(express, null, null, true, true) System.out.println("表达式计算:" + express + " = " + r) }}
以上, 解决了引用的问题。
下面进入正题, 使用scala来操作简单的四则运算:
val runner = new ExpressRunner(false, true) var context = new DefaultContext[String, AnyRef] context.put("a", 23) val r = runner.executeFloat(express, context, null, true, false) System.out.println("表达式计算: " + express + " = " + r)
那么这里的context在java中是一个HashMap《K,V》, 泛型的指向对象V在scala中则会自动转成AnyRef。
scala中的int、long 、 float等都继承AnyVal, 只有String继承AnyRef,所以上面的demo中无法实现。所以下面强制转换String尝试
val runner = new ExpressRunner() var context = new DefaultContext[String, AnyRef]// context+=("a"->null) context.put("a", 1.toString) context.put("a", 2.toString) context.put("c", 3.toString) val express: String = "a+b*c" val r = runner.execute(express, context, null, true, false, null) System.out.println("表达式计算: " + express + " = " + r)
ERROR: String转换Number异常
了解一下源码中的参数解析:
* @param expressString 程序文本 * @param context 执行上下文 * @param errorList 输出的错误信息List * @param isCache 是否使用Cache中的指令集 * @param isTrace 是否输出详细的执行指令信息 * @param aLog 输出的log
Error原因: qlExpress在上下文代入时会把参数值强制转换为Number, 因为scala的语言这里把数值内容包装成String,所以转换异常。
解决: 修改源码OperatorOfNumber.java(进入qlexpress项目中)
a.将文件中的所有 (Number)op1,(Number)op2 修改为new BigDecimal(op1.toString()),new BigDecimal(op2.toString())
例如:
修改前->PreciseNumberOperator.addPrecise((Number)op1,(Number)op2)
修改后->PreciseNumberOperator.addPrecise(new BigDecimal(op1.toString()),new BigDecimal(op2.toString()))
b. qlExpress对字符内容的 + 运算有特殊处理, 这里需要修改
public static Object add(Object op1, Object op2,boolean isPrecise) throws Exception { if(op1 == null){ op1 = "null"; } if(op2 == null){ op2 = "null"; } //因为scala用字符串类型包装数据内容, 这里需要禁用// if (op1 instanceof String || op2 instanceof String) {// return op1.toString() + op2.toString();// } if(isPrecise==true){ return PreciseNumberOperator.addPrecise(new BigDecimal(op1.toString()),new BigDecimal(op2.toString())); }else{ return NormalNumberOperator.addNormal(new BigDecimal(op1.toString()),new BigDecimal(op2.toString())); } }
修改完qlexpress, 重新打包测试
val runner = new ExpressRunner(false, true) val express: String = "a+b*c-d/e" var context1 = new DefaultContext[String, AnyRef] var a: Any = 2.20 var b: Any = 2 var c: Any = 3 var d: Any = 3 var e: Any = 1 context1.put("a", a.toString) context1.put("b", b.toString) context1.put("c", c.toString) context1.put("d", d.toString) context1.put("e", e.toString) val r1 = runner.execute(express, context1, null, true, true) System.out.println("表达式计算: " + express + " = " + r1)
1: STAT_BLOCK:STAT_BLOCK STAT_BLOCK2: STAT_SEMICOLON:STAT_SEMICOLON STAT_SEMICOLON3: -:- -4: +:+ +5: a:ID ID5: *:* *6: b:ID ID6: c:ID ID4: /:/ /5: d:ID ID5: e:ID ID表达式计算: a+b*c-d/e = 5.2Process finished with exit code 0
测试通过!
- QLExpress使用问题
- QLExpress 规则引擎使用介绍
- 结合 spring ,使用QLExpress做一个淘宝的场景模型,对于场景的描述可以参照这个demo
- QLExpress脚本语言技术讲解(6)-------QLExpress的缓存管理
- QLExpress脚本语言技术讲解(1)
- [Java代码] java数学表达式计算 QLExpress
- QLExpress解析公式进行计算业务
- qlExpress实践手册-spring的融合
- qlExpress实践手册-常用语法介绍
- QLExpress脚本语言技术讲解(3) -----QL的性能描述
- QLExpress计算等本等息、等额本息、等额本金
- QLExpress脚本语言技术讲解(4)------扩展QLExpress来管理spring的bean,写出简单的脚本语言框架
- QLExpress脚本语言技术讲解(2) -----QL的基本执行过程
- QLExpress脚本语言技术讲解(5)------对脚本语言的进一步优化,变成中文的脚本语言
- WPPackager使用中的问题
- Tomcat使用中的问题
- 使用MySQL中文问题
- treeview使用问题集锦
- aar在eclipse中使用
- "DeepNight-in-kotlin"一个纯看妹纸的 Kotlin 开源项目
- php在用js_encode()转换时,实现斜杠不转义
- Ubuntu下如何修改文件或者文件夹的权限
- elasticsearch系列-什么是Mapping
- QLExpress使用问题
- vue elementUI之Form表单 验证
- 安卓MVP开发模式---初识
- spring quartz详解
- ccproxy8.0破解版
- 讯飞现在语音SDK集成封装
- 用Mac终端编写、编译C程序
- 12项IT技能
- Redis事务机制和分布式锁