JEXL动态计算表达式

定义


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

 

 

 

 

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值