定义

Java Expression Language (JEXL) 是一个表达式语言引擎,可以用来校验数据。

背景 
项目中,需要配置一些规则,然后根据动态的数据去验证规则。比如配置如下的规则:

或者这种

计算方式需要通过配置来完成,使用这个方式就非常便捷了。

案例:

人数大于5,并且名称包含 “test” 才能验证通过。
按照传统的思路,一般就是写死代码,如:

if(num > 5 && name.contains("test")){return true;
}

但是,如果规则变成了人数等于6,那就要去修改代码(虽然值可以动态获取,但是 > 不能动态改为 = ),比较麻烦。那么就换一种思路,做成可以配置的,按照上面的规则,就是配置成:

纬度1 公式1 值1 && 纬度2 公式2 值2
${num} > 5 && ${name}.contains(“test”)

在为变量设置具体值。

10 > 5 && “test jexl”.contains(“test”)

那么问题来了,怎么动态验证这个表达式的结果呢?
为了计算上面表达式的结果,这时候就需要用到 JEXL 了,我们直接看代码。

<dependency><groupId>org.apache.commons</groupId><artifactId>commons-jexl3</artifactId><version>3.1</version>
</dependency>
JexlContext jc = new MapContext();
JexlExpression expression = new JexlBuilder().create().createExpression("10 > 5 && \"test jexl\".contains(\"test\")");
Object result = expression.evaluate(jc);
System.out.println(result);

运行结果为:true
1 > 5 && “test jexl”.contains(“test”)

JEXL 设置参数

JEXL 也可以通过设置参数来计算结果,比如公式为:x - y

那么我们可以通过 JEXL 来设置 x 和 y 的值。

JexlContext jc = new MapContext();
jc.set("x", 10);
jc.set("y", 20);
JexlExpression e = new JexlBuilder().create().createExpression("x - y");
Object result = e.evaluate(jc);
System.out.println(result);

运行结果为:-10
这边有个容易出错的地方,jc.set()第二个参数为 object 类型,需要根据实际类型来传值(比如值为 string 的时候需要带引号),否则可能会报错。

正则表达式匹配

首先写一个公共方法:

public class Util {public static boolean regMatch(String regEx, String str) {Pattern pattern = Pattern.compile(regEx);return pattern.matcher(str).matches();}
}

下面是使用JEXL调用的方法

public void RL() {JexlContext jc = new MapContext();String str = "一二三四五六七八九十";jc.set("Util", new Util());jc.set("str", str);jc.set("ans", "");String expression = "ans = Util.regMatch(\"[\u4e00-\u9fa5]{10,}\",str)";Expression e = new JexlEngine().createExpression(expression);e.evaluate(jc);System.out.println(jc.get("ans"));
}

循环
JEXL支持两种循环方式:

for(item : list) {x = x + item;
}
while (x lt 10) {x = x + 2;
}

在JDK1.6之后内部也支持使用ScriptEngine,功能也很强大,针对ScriptEngine我有另外一篇博客,感兴趣的可以去看下

上面介绍了适用和案例接下面我们看下源码他们是怎么实现的:

先介绍上面几个陌生的类:
MapContext
JexlBuilder
方法:
createExpression
evaluate

本文摘自:https://blog.csdn.net/qqfo24/article/details/88252313    https://blog.csdn.net/u012468264/article/details/56679802

JEXL动态计算表达式相关推荐

  1. 在C#中解决动态计算表达式的问题(如字符串Sin(1)+Cos(2),执行并得出结果)

    前一阵公司老总要求我去重构一个同事的程序,里面有各种计算公式,如下图 这个公式的算法是这样 0.058419 + 0.084612 * (log10( 第二个文本框的值 / 第一个文本框的值)) + ...

  2. php字符串转换表达式,php处理字符串格式的计算表达式

    有时候我们对每一种产品都有一个提成公式,而这个计算提成的公式是以字符串格式存在表中的 当我们用这个计算公式时,他并不像我们写的:$a=2+3*5;这样简单的能计算出结果,而它是个字符串 所以,我们就必 ...

  3. Eval.cs的改进版 动态编译类,可以计算表达式,也可以调用系统中的类

    Eval.cs的改进版 动态编译类,可以计算表达式,也可以调用系统中的类 /* 动态编译类,可以计算表达式,也可以调用系统中的类 调用方式:     return new XXXXXXX.Eval() ...

  4. power bi 日期计算_PowerBI 动态计算周内日权重指数

    在很多行业,尤其是零售业,其销售规律在一周内呈现一定的特点. 例如:平时有一种购买特点:周末有一种购买特点. 故而一周内的星期一到星期日呈现一定的权重分布. 周内日权重分布 1 到 12 表示月序号: ...

  5. 基于三相坐标系状态方程的感应电动机起动动态计算matlab程序

    基于三相坐标系状态方程的感应电动机起动动态计算matlab程序 1 异步电动机动态数学模型的性质 电磁耦合是机电能量转换的必要条件,电流与磁通的乘积产生转矩,转速与磁通的乘积得到感应电动势.无论是直流 ...

  6. 理解 css rem与动态计算rem

    1.rem定义? 首先css3规定1rem = html根节点的font-size,rem也就是root em简写. 为了方便计算通常设置根节点font-size = 100px 那么 1rem = ...

  7. css如何动态计算,CSS中的动态计算

    自从CSS的calc()函数得到浏览器的支持起,在CSS中就可以做一些简单的数学运算.如果你阅读过 图解CSS系列 中的 <CSS函数>一文的话,你会发现现在或将来有更多的函数可以直接帮助 ...

  8. SqlDataReader生成动态Lambda表达式

    上一扁使用动态lambda表达式来将DataTable转换成实体,比直接用反射快了不少.主要是首行转换的时候动态生成了委托. 后面的转换都是直接调用委托,省去了多次用反射带来的性能损失. 今天在对Sq ...

  9. 异常“本机框架位于调用堆栈顶部,因此无法计算表达式的值”的解决办法

    异常:本机框架位于调用堆栈之上,无法计算表达式的值 原因: 如果使用 Response.End.Response.Redirect 或 Server.Transfer 方法,将出现 ThreadAbo ...

最新文章

  1. MySQL中的联合索引学习教程
  2. h5软盘占位把定位内容往上顶_安徽省计算机一级考试选择题、操作题、打字题库2012年上半年版.xls...
  3. VirtualApp技术黑产利用研究报告
  4. 属于HTML文档头部相关标记,下列选项中,属于HTML文档头部相关标记的是 答案:title/titlemeta /...
  5. linux进程控制命令
  6. python opengl_Python环境搭建之OpenGL
  7. @RequestParam详解
  8. js基础--变量、数据类型、循环、判断、函数定义
  9. Scala paralle
  10. 结束SpringMVC
  11. PHP无限极分类巧用引用生成树
  12. ubuntu phpmyadmin 404 not found
  13. 三步完成自动抢票,又一款春节免费抢票神器推荐
  14. Python 实例教程100例
  15. 图像处理MATLAB(图像分割)
  16. Userscript+ 去除广告
  17. 用Python找回微信撤回信息
  18. opencv4.5.2嵌入式移植
  19. 套接字的连接(服务器与客户端一对一的连接)
  20. Lifeline功能介绍04——个人课程的查看及管理

热门文章

  1. RINEX 2.11 观测值文件格式说明
  2. 英语练习32 Poor Amy
  3. Windows事件查看器_ID一览表
  4. 傅里叶变换复数形式的实部代表什么_「趣味数学」傅里叶变换及其在人工智能中的应用...
  5. [解密] DNA存储技术究竟牛在哪里?
  6. 设计模式七大原则介绍
  7. 操作系统经典20题总结==上岸
  8. BMR(基础代谢率)计算器
  9. Ubuntu系统下C语言编译以及Makefile编译C语言程序
  10. Java中 VO、 PO、DO、DTO、 BO、 QO、DAO、POJO和util、service、tool