diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4cbe5aa12..a2ee4a19e 100755
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,6 +10,7 @@
* 【core 】 AnnotationUtil类支持Lambda获取某注解属性值(pr#827@Gitee)
* 【core 】 CharUtil.isBlank添加Hangul Filler字符(issue#I5UGSQ@Gitee)
* 【poi 】 优化合并单元格读取(issue#I5UJZ1@Gitee)
+* 【extra 】 增加QLExpress支持(issue#2653@Github)
### 🐞Bug修复
* 【poi 】 修复ExcelReader读取只有标题行报错问题(issue#I5U1JA@Gitee)
diff --git a/hutool-extra/pom.xml b/hutool-extra/pom.xml
index c4727a9d6..97aa623e5 100755
--- a/hutool-extra/pom.xml
+++ b/hutool-extra/pom.xml
@@ -453,7 +453,7 @@
org.springframework
spring-expression
- 5.3.20
+ 5.3.23
compile
true
@@ -464,6 +464,13 @@
compile
true
+
+ com.alibaba
+ QLExpress
+ 3.3.0
+ compile
+ true
+
org.apache.commons
diff --git a/hutool-extra/src/main/java/cn/hutool/extra/expression/engine/qlexpress/QLExpressEngine.java b/hutool-extra/src/main/java/cn/hutool/extra/expression/engine/qlexpress/QLExpressEngine.java
new file mode 100755
index 000000000..d941685d1
--- /dev/null
+++ b/hutool-extra/src/main/java/cn/hutool/extra/expression/engine/qlexpress/QLExpressEngine.java
@@ -0,0 +1,38 @@
+package cn.hutool.extra.expression.engine.qlexpress;
+
+import cn.hutool.extra.expression.ExpressionEngine;
+import cn.hutool.extra.expression.ExpressionException;
+import com.ql.util.express.DefaultContext;
+import com.ql.util.express.ExpressRunner;
+
+import java.util.Map;
+
+/**
+ * QLExpress引擎封装
+ * 见:https://github.com/alibaba/QLExpress
+ *
+ * @author looly
+ * @since 5.8.9
+ */
+public class QLExpressEngine implements ExpressionEngine {
+
+ private final ExpressRunner engine;
+
+ /**
+ * 构造
+ */
+ public QLExpressEngine() {
+ engine = new ExpressRunner();
+ }
+
+ @Override
+ public Object eval(final String expression, final Map context) {
+ final DefaultContext defaultContext = new DefaultContext<>();
+ defaultContext.putAll(context);
+ try {
+ return engine.execute(expression, defaultContext, null, true, false);
+ } catch (final Exception e) {
+ throw new ExpressionException(e);
+ }
+ }
+}
diff --git a/hutool-extra/src/main/java/cn/hutool/extra/expression/engine/qlexpress/package-info.java b/hutool-extra/src/main/java/cn/hutool/extra/expression/engine/qlexpress/package-info.java
new file mode 100755
index 000000000..f3c4cf1e5
--- /dev/null
+++ b/hutool-extra/src/main/java/cn/hutool/extra/expression/engine/qlexpress/package-info.java
@@ -0,0 +1,7 @@
+/**
+ * QLExpress引擎封装
+ * 见:https://github.com/alibaba/QLExpress
+ *
+ * @author looly
+ */
+package cn.hutool.extra.expression.engine.qlexpress;
diff --git a/hutool-extra/src/main/resources/META-INF/services/cn.hutool.extra.expression.ExpressionEngine b/hutool-extra/src/main/resources/META-INF/services/cn.hutool.extra.expression.ExpressionEngine
index df7e3a18c..33aa4f4b6 100644
--- a/hutool-extra/src/main/resources/META-INF/services/cn.hutool.extra.expression.ExpressionEngine
+++ b/hutool-extra/src/main/resources/META-INF/services/cn.hutool.extra.expression.ExpressionEngine
@@ -3,4 +3,5 @@ cn.hutool.extra.expression.engine.jexl.JexlEngine
cn.hutool.extra.expression.engine.mvel.MvelEngine
cn.hutool.extra.expression.engine.jfireel.JfireELEngine
cn.hutool.extra.expression.engine.spel.SpELEngine
-cn.hutool.extra.expression.engine.rhino.RhinoEngine
\ No newline at end of file
+cn.hutool.extra.expression.engine.rhino.RhinoEngine
+cn.hutool.extra.expression.engine.qlexpress.QLExpressEngine
diff --git a/hutool-extra/src/test/java/cn/hutool/extra/expression/ExpressionUtilTest.java b/hutool-extra/src/test/java/cn/hutool/extra/expression/ExpressionUtilTest.java
index 40865ec27..1b04968ff 100755
--- a/hutool-extra/src/test/java/cn/hutool/extra/expression/ExpressionUtilTest.java
+++ b/hutool-extra/src/test/java/cn/hutool/extra/expression/ExpressionUtilTest.java
@@ -4,6 +4,7 @@ import cn.hutool.core.lang.Dict;
import cn.hutool.extra.expression.engine.jexl.JexlEngine;
import cn.hutool.extra.expression.engine.jfireel.JfireELEngine;
import cn.hutool.extra.expression.engine.mvel.MvelEngine;
+import cn.hutool.extra.expression.engine.qlexpress.QLExpressEngine;
import cn.hutool.extra.expression.engine.rhino.RhinoEngine;
import cn.hutool.extra.expression.engine.spel.SpELEngine;
import org.junit.Assert;
@@ -26,7 +27,7 @@ public class ExpressionUtilTest {
@Test
public void jexlTest(){
- ExpressionEngine engine = new JexlEngine();
+ final ExpressionEngine engine = new JexlEngine();
final Dict dict = Dict.create()
.set("a", 100.3)
@@ -38,18 +39,18 @@ public class ExpressionUtilTest {
@Test
public void jexlScriptTest(){
- ExpressionEngine engine = new JexlEngine();
+ final ExpressionEngine engine = new JexlEngine();
- String exps2="if(a>0){return 100;}";
- Map map2=new HashMap<>();
+ final String exps2="if(a>0){return 100;}";
+ final Map map2=new HashMap<>();
map2.put("a", 1);
- Object eval1 = engine.eval(exps2, map2);
+ final Object eval1 = engine.eval(exps2, map2);
Assert.assertEquals(100, eval1);
}
@Test
public void mvelTest(){
- ExpressionEngine engine = new MvelEngine();
+ final ExpressionEngine engine = new MvelEngine();
final Dict dict = Dict.create()
.set("a", 100.3)
@@ -61,7 +62,7 @@ public class ExpressionUtilTest {
@Test
public void jfireELTest(){
- ExpressionEngine engine = new JfireELEngine();
+ final ExpressionEngine engine = new JfireELEngine();
final Dict dict = Dict.create()
.set("a", 100.3)
@@ -73,7 +74,7 @@ public class ExpressionUtilTest {
@Test
public void spELTest(){
- ExpressionEngine engine = new SpELEngine();
+ final ExpressionEngine engine = new SpELEngine();
final Dict dict = Dict.create()
.set("a", 100.3)
@@ -85,7 +86,7 @@ public class ExpressionUtilTest {
@Test
public void rhinoTest(){
- ExpressionEngine engine = new RhinoEngine();
+ final ExpressionEngine engine = new RhinoEngine();
final Dict dict = Dict.create()
.set("a", 100.3)
@@ -95,4 +96,16 @@ public class ExpressionUtilTest {
Assert.assertEquals(-143.8, (double)eval, 0);
}
+ @Test
+ public void qlExpressTest(){
+ final ExpressionEngine engine = new QLExpressEngine();
+
+ final Dict dict = Dict.of()
+ .set("a", 100.3)
+ .set("b", 45)
+ .set("c", -199.100);
+ final Object eval = engine.eval("a-(b-c)", dict);
+ Assert.assertEquals(-143.8, (double)eval, 0);
+ }
+
}