RuleEngine规则引擎底层改造AviatorScript 之公式规则

2024-04-09 09:28

本文主要是介绍RuleEngine规则引擎底层改造AviatorScript 之公式规则,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前情提要,看上一个文章,具体要实现的效果就是
在这里插入图片描述
当然上来的问题就是前端的问题,这个框首先他们用的是富文本,富文本传到后台的结果是前端脚本,带着h5的标签,后面改成了这个,当时这个东西其实和后端关系不大,就是如何处理换行符而已,使用这个之后换行符变成了/n
其实我们也是比着普通规则新建的一个功能,不过有很多的自己的设计
他们的实现是这样的

     */@Overridepublic Object run(RunTestRequest runTestRequest) {log.info("模拟运行规则:{}", runTestRequest.getCode());RuleEngineGeneralRulePublish rulePublish = this.ruleEngineGeneralRulePublishManager.lambdaQuery().eq(RuleEngineGeneralRulePublish::getStatus, runTestRequest.getStatus()).eq(RuleEngineGeneralRulePublish::getGeneralRuleCode, runTestRequest.getCode()).eq(RuleEngineGeneralRulePublish::getWorkspaceCode, runTestRequest.getWorkspaceCode()).one();if (rulePublish == null) {// 如果测试找不到,用线上  此场景出现在只有一个线上的时候rulePublish = this.ruleEngineGeneralRulePublishManager.lambdaQuery().eq(RuleEngineGeneralRulePublish::getStatus, DataStatus.PRD.getStatus()).eq(RuleEngineGeneralRulePublish::getGeneralRuleCode, runTestRequest.getCode()).eq(RuleEngineGeneralRulePublish::getWorkspaceCode, runTestRequest.getWorkspaceCode()).one();if (rulePublish == null) {throw new ValidException("找不到可运行的规则数据:{},{},{}", runTestRequest.getWorkspaceCode(), runTestRequest.getCode(), runTestRequest.getStatus());}}Input input = new DefaultInput(runTestRequest.getParam());log.info("初始化规则引擎");RuleEngineConfiguration ruleEngineConfiguration = new RuleEngineConfiguration();Container.Body<GeneralRule> generalRuleContainer = ruleEngineConfiguration.getGeneralRuleContainer();GeneralRule rule = GeneralRule.buildRule(rulePublish.getData());generalRuleContainer.add(rule);GeneralRuleEngine engine = new GeneralRuleEngine(ruleEngineConfiguration);// 加载变量engine.getConfiguration().setEngineVariable(this.ruleEngineConfiguration.getEngineVariable());return engine.execute(input, runTestRequest.getWorkspaceCode(), runTestRequest.getCode());}

然后我们改成了这个样子

    @Overridepublic Object formularun(RunTestRequest runTestRequest) {QueryWrapper<RuleEngineFunction2> wrapper = new QueryWrapper<>();List<RuleEngineFunction2> list = ruleEngineFunction2Manager.list(wrapper);for (int i = 0; i < list.size(); i++) {RuleEngineFunction2 ruleEngineFunction2 = list.get(i);//获取设置对应的方法名String className = ruleEngineFunction2.getClassName();String functionName = ruleEngineFunction2.getFunctionName();if (applicationContext.containsBean(className)) {AviatorFunction abstractFunction = (AviatorFunction)applicationContext.getBean(className);AviatorEvaluator.addFunction(abstractFunction);}}String funcation = runTestRequest.getFuncation();funcation = removeHtmlTags(funcation);System.out.println(funcation);Expression compiledExp = AviatorEvaluator.compile(funcation);Map<String, Object> param = runTestRequest.getParam();String res = String.valueOf(compiledExp.execute(param));System.out.println(res);return null;}public  String removeHtmlTags(String input) {return input.replaceAll("<[^>]*>", "");}
}

实现方式,但是这个时候出现了问题,就是函数底层实现的时候出现了问题,然后我们将函数的实现修改了,这个代码就几乎没有什么变动了,这个时候有一个另外的需求。就是需要有一个函数nvlFunction,这个函数是用来干啥的呢,就是说处理入参的,出现了这个函数就是表示有入参,这个函数一共两个参数,第一个参数,是取自函数这个功能的字段,要求是函数功能的函数code值,用来表示入参,另一个参数就是当这个入参不输入的时候,将这个参数赋值给对应的函数。
听着不难,实现的话我也是觉得挺简单的

@Function
public class NvlFunction extends AbstractFunction {@Overridepublic String getName() {return "nvlFunction";}@Overridepublic AviatorObject call(Map<String, Object> env, AviatorObject arg1, AviatorObject arg2) {String letter1 = FunctionUtils.getStringValue(arg1, env);String letter2 = FunctionUtils.getStringValue(arg2, env);System.out.println("letter1"+letter1);System.out.println("letter2"+letter2);return new AviatorString(letter2);}
}

初版,发现不大行,如果参数没有穿进去不大对,

@Function
public class NvlFunction extends AbstractFunction {@Overridepublic String getName() {return "nvlFunction";}@Overridepublic AviatorObject call(Map<String, Object> env, AviatorObject arg1, AviatorObject arg2) {if (arg1 != null && !"".equals(arg1)) {return arg1;}return arg2;}
}

然后换成了这个,发现也是不大行,即使为空的话这个对象AviatorObject 也不会为null

@Function
public class NvlFunction extends AbstractFunction {@Overridepublic String getName() {return "nvlFunction";}@Overridepublic AviatorObject call(Map<String, Object> env, AviatorObject arg1, AviatorObject arg2) {Object param1 = arg1.getValue(env);if (param1 == null || param1.toString().isEmpty()) {return arg2;} else {return arg1;}}
}

发现了只有这个value是null,当这个入参是空的时候,至此改造全部完成了,剩下的就是他原本框架的小bug的修改以及小功能的新增了。

这篇关于RuleEngine规则引擎底层改造AviatorScript 之公式规则的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/887776

相关文章

详解nginx 中location和 proxy_pass的匹配规则

《详解nginx中location和proxy_pass的匹配规则》location是Nginx中用来匹配客户端请求URI的指令,决定如何处理特定路径的请求,它定义了请求的路由规则,后续的配置(如... 目录location 的作用语法示例:location /www.chinasem.cntestproxy

利用Python实现添加或读取Excel公式

《利用Python实现添加或读取Excel公式》Excel公式是数据处理的核心工具,从简单的加减运算到复杂的逻辑判断,掌握基础语法是高效工作的起点,下面我们就来看看如何使用Python进行Excel公... 目录python Excel 库安装Python 在 Excel 中添加公式/函数Python 读取

最新Spring Security实战教程之表单登录定制到处理逻辑的深度改造(最新推荐)

《最新SpringSecurity实战教程之表单登录定制到处理逻辑的深度改造(最新推荐)》本章节介绍了如何通过SpringSecurity实现从配置自定义登录页面、表单登录处理逻辑的配置,并简单模拟... 目录前言改造准备开始登录页改造自定义用户名密码登陆成功失败跳转问题自定义登出前后端分离适配方案结语前言

Java的volatile和sychronized底层实现原理解析

《Java的volatile和sychronized底层实现原理解析》文章详细介绍了Java中的synchronized和volatile关键字的底层实现原理,包括字节码层面、JVM层面的实现细节,以... 目录1. 概览2. Synchronized2.1 字节码层面2.2 JVM层面2.2.1 ente

MySQL中Next-Key Lock底层原理实现

《MySQL中Next-KeyLock底层原理实现》Next-KeyLock是MySQLInnoDB存储引擎中的一种锁机制,结合记录锁和间隙锁,用于高效并发控制并避免幻读,本文主要介绍了MySQL中... 目录一、Next-Key Lock 的定义与作用二、底层原理三、源代码解析四、总结Next-Key L

MySQL常见的存储引擎和区别说明

《MySQL常见的存储引擎和区别说明》MySQL支持多种存储引擎,如InnoDB、MyISAM、MEMORY、Archive、CSV和Blackhole,每种引擎有其特点和适用场景,选择存储引擎时需根... 目录mysql常见的存储引擎和区别说明1. InnoDB2. MyISAM3. MEMORY4. A

MySQL InnoDB引擎ibdata文件损坏/删除后使用frm和ibd文件恢复数据

《MySQLInnoDB引擎ibdata文件损坏/删除后使用frm和ibd文件恢复数据》mysql的ibdata文件被误删、被恶意修改,没有从库和备份数据的情况下的数据恢复,不能保证数据库所有表数据... 参考:mysql Innodb表空间卸载、迁移、装载的使用方法注意!此方法只适用于innodb_fi

MySQL中的MVCC底层原理解读

《MySQL中的MVCC底层原理解读》本文详细介绍了MySQL中的多版本并发控制(MVCC)机制,包括版本链、ReadView以及在不同事务隔离级别下MVCC的工作原理,通过一个具体的示例演示了在可重... 目录简介ReadView版本链演示过程总结简介MVCC(Multi-Version Concurr

关于Gateway路由匹配规则解读

《关于Gateway路由匹配规则解读》本文详细介绍了SpringCloudGateway的路由匹配规则,包括基本概念、常用属性、实际应用以及注意事项,路由匹配规则决定了请求如何被转发到目标服务,是Ga... 目录Gateway路由匹配规则一、基本概念二、常用属性三、实际应用四、注意事项总结Gateway路由

Redis 多规则限流和防重复提交方案实现小结

《Redis多规则限流和防重复提交方案实现小结》本文主要介绍了Redis多规则限流和防重复提交方案实现小结,包括使用String结构和Zset结构来记录用户IP的访问次数,具有一定的参考价值,感兴趣... 目录一:使用 String 结构记录固定时间段内某用户 IP 访问某接口的次数二:使用 Zset 进行