Java Apache Jexl规则引擎初体验

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 一、模板引擎的选择?
  • 二、什么是JEXL规则引擎?
          • 优点
          • 缺点
  • 三、其他规则引擎
  • 四、示例
    • 1.引入依赖
    • 2.方法示例
    • 3、代码解释
    • 4、效果
    • ![import java.util.*;](https://img-blog.csdnimg.cn/direct/560fb9361ba14b6ab72d42d2f49922ae.png)
  • 总结


前言

最近产品提了一个需求,通过前端页面点击生成表达式。来,请看大屏幕。。。错了,请看需求原型
在这里插入图片描述
通过前端按钮点击生成在公式展示栏的表达式,这里先不计较公式正确与否,就默认生成的公式一定是正确的,而生成的公式会作为传参传递到后端接口。


一、模板引擎的选择?

这里的公式仅用于匹配通过接口传入的类或者参数是否匹配,所以,这里不需要引入过重的表达式引擎,最终选择了Apache Jexl规则引擎

二、什么是JEXL规则引擎?

Apache Jexl(以下简称Jexl)是一种基于Java的表达式语言,用于在Java应用程序中计算和操作值。它可以用作规则引擎的一部分,但不是专门为此而设计的。与其他专为规则引擎而设计的引擎相比,Jexl具有以下优点和缺点。

优点
  • 易于学习和使用:Jexl的语法简单直观,易于理解和使用。它的API也很容易上手,对于新手来说非常友好。
  • 灵活性高:Jexl具有很高的灵活性,允许用户自定义函数、变量和操作符等,以满足各种需求。
  • 与Java集成良好:Jexl是基于Java的,因此可以非常方便地与Java应用程序集成。它可以轻松地与Java对象交互,并使用Java的反射机制来访问类和方法。
缺点
  • 不是专为规则引擎设计:尽管可以将Jexl用作规则引擎的一部分,但它并不是专为此而设计的。因此,在处理复杂的业务规则时,可能会存在一些限制和不足。
  • 缺少规则管理功能:Jexl本身只提供了表达式解析和计算功能,如果需要更复杂的规则管理功能,例如规则编辑、版本控制和审批流程等,需要自行实现或使用其他规则引擎。
  • 性能较差:由于Jexl是解释型语言,因此它的性能相对较低。如果需要处理大量数据或高并发场景,则可能需要考虑使用其他规则引擎。

三、其他规则引擎

市面上除了Jexl之外,还有许多其他的规则引擎可供选择,这里简单介绍一些在市面上比较常见的规则引擎:

  1. Drools:Drools 是一个开源规则引擎,它允许开发人员将业务逻辑与应用程序代码分离。它使用基于规则的语言(DRL)来表示和执行规则,并提供从多个数据源中自动推断输出结果的能力。

  2. Jess:Jess 是另一个基于规则的编程语言,它被设计为与 Java 集成。它可以用于构建专家系统、商业决策支持系统等。Jess 还包括一些高级特性,例如模式匹配和对象操作。

  3. Easy Rules:Easy Rules 是一个轻量级的规则引擎框架,它允许开发人员在应用程序中定义和执行简单的规则。它支持注解和 Lambda 表达式,并提供了与 Spring 和 CDI 的集成。

  4. Apache Spark MLlib:Apache Spark MLlib 是一个大规模机器学习库,它包含了许多算法和工具用于分类、回归、聚类和协同过滤等任务。它还提供了一组规则引擎,用于处理流数据和批数据。

  5. NRules:NRules 是一个 .NET 规则引擎,它允许开发人员定义和执行规则。它使用 C# 语言编写,并提供了与 LINQ 的集成,使得开发人员可以使用类似 SQL 的查询来过滤数据

四、示例

1.引入依赖

在 pom.xml 文件中添加以下依赖项:

	<dependency><groupId>org.apache.commons</groupId><artifactId>commons-jexl3</artifactId><version>3.2</version></dependency>

2.方法示例

代码如下(示例):

import org.apache.commons.jexl3.JexlContext;
import org.apache.commons.jexl3.MapContext;import java.util.*;public static void main(String[] args) {// 中文表达式String expStr = "(长<=120 且 宽<=60 且 高<=60 且 围长<=300 且 容积>150 且 重量<=31.5)" +" 或 (长>=121 且 长<=175 且 宽<=60 且 高<=60 且 围长<=300 且 容积<=150 且 重量<=31.5)" +" 或 (长<=120 且 宽>70 且 高<=60 且 围长<=300 且 容积<=150 且 重量<=31.5)";// Step 1:将中文且、或替换成java中的&&、||String replaceAfterStr = expStr.replaceAll("且", "&&").replaceAll("或", "||").replaceAll("围长", "perimeter").replaceAll("容积", "volume").replaceAll("重量", "weight").replaceAll("长", "length").replaceAll("宽", "width").replaceAll("高", "height");System.out.println("将中文且、或替换后的表达式:\n" + replaceAfterStr);// Step 2: 按照特定格式切割替换后表达式:"||"String[] split = replaceAfterStr.split("\\|\\|");List<String> splitExpStr = Arrays.asList(split);System.out.println("切割后的表达式:\n" + String.join("\n", splitExpStr));// Step 3:校验表达式是否符合JexlEngine engine = new JexlEngine();JexlContext context = new MapContext();context.set("length", 119);context.set("width", 59);context.set("height", 59);context.set("perimeter", 299);context.set("volume", 151);context.set("weight", 31.5);for (String s : splitExpStr) {Object evaluate = engine.getEngine().createExpression(s).evaluate(context);if (Boolean.FALSE.equals(evaluate)) {System.out.println("context不符合当前表达式:" + s);} else {System.out.println("context符合当前表达式:" + s);}}}

3、代码解释

这个方法的功能是通过解析和校验一个给定的中文表达式,来判断某些商品是否符合特定条件。具体步骤如下:

  1. 将中文的“且”和“或”替换为Java中的“&&”和“||”,并将其他中文关键词替换为对应的英文关键词。
  2. 将替换后的表达式按照“||”进行分割,得到多个子表达式。
  3. 创建一个JexlEngine对象用于解析表达式,并创建一个JexlContext对象用于设置待校验的上下文信息(长度、宽度、高度、围长、容积、重量)。
  4. 遍历分割后的子表达式,使用JexlEngine对每个子表达式进行求值,并根据求值结果判断上下文是否符合该子表达式。
  5. 最终输出符合或不符合子表达式的上下文信息。

4、效果

这个是运行结果

import java.util.*;

总结

这里说个问题,JEXL对于单表达式(例如:长<=120)组成的组合表达式是可以解析的,但是,如果你的单表达式写成(例:121<=长<=175)组成的组合表达式,Jexl是没办法解析的,所以,这种单表达式(例:121<=长<=175)你需要转换成(长>=121 且 长<=175),这样Jexl就会解析没问题

表达式:21<=长<=175解析报错信息

将中文且、或替换后的表达式:
(length<=120 && width<=60 && height<=60 && perimeter<=300 && volume>150 && weight<=31.5) || (121<=length<=175 && width<=60 && height<=60 && perimeter<=300 && volume<=150 && weight<=31.5) || (length<=120 && width>70 && height<=60 && perimeter<=300 && volume<=150 && weight<=31.5)
切割后的表达式:
(length<=120 && width<=60 && height<=60 && perimeter<=300 && volume>150 && weight<=31.5) (121<=length<=175 && width<=60 && height<=60 && perimeter<=300 && volume<=150 && weight<=31.5) (length<=120 && width>70 && height<=60 && perimeter<=300 && volume<=150 && weight<=31.5)
context符合当前表达式:(length<=120 && width<=60 && height<=60 && perimeter<=300 && volume>150 && weight<=31.5) 
Exception in thread "main" org.apache.commons.jexl3.JexlException$Parsing: com.smallrig.logistics.service.impl.LogisticsFreightOverrunRuleServiceImpl.main:257@1:13 parsing error in '<='at org.apache.commons.jexl3.JexlEngine.createExpression(JexlEngine.java:335)at com.smallrig.logistics.service.impl.LogisticsFreightOverrunRuleServiceImpl.main(LogisticsFreightOverrunRuleServiceImpl.java:257)

原创不易,望一键三连 (^ _ ^)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/14386.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

VMware虚拟机Ubuntu 22.04.4 LTS系统 NAT网络设置异常解决

现象&#xff1a; 近日&#xff0c;一直工作正常的虚拟机莫名出现网络无法连接的情况。 参考网上的各种教程&#xff0c;终于解决问题。 如遇到类似情况的&#xff0c;可以尝试这个方式&#xff0c;看能否解决问题。 网络连接&#xff1a;采用NAT模式 异常&#xff1a;网络图标…

C++数据结构——哈希表

前言&#xff1a;本篇文章将继续进行C数据结构的讲解——哈希表。 目录 一.哈希表概念 二.哈希函数 1.除留取余法 三.哈希冲突 1.闭散列 线性探测 &#xff08;1&#xff09;插入 &#xff08;2&#xff09;删除 2. 开散列 开散列概念 四.闭散列哈希表 1.基本框架 …

场内期权怎么开户?佣金手续费最低是多少?

今天期权懂带你了解场内期权怎么开户&#xff1f;佣金手续费最低是多少&#xff1f;我国的首个场内期权是50ETF期权&#xff0c;随着投资者对期权产品日渐熟悉&#xff0c;投资者参与数量与交易量稳步增长。 场内期权怎么开户&#xff1f; 满足资金要求&#xff1a;根据监管要…

自动打卡脚本

奕辅导自动打卡脚本 打卡脚本&#xff0c;使用前需手动打卡一次并需要抓包&#xff0c;在其中找到相关的token。 # -*- encoding:utf-8 -*-import requests import jsonpunch_in_data {"questionnairePublishEntityId": "1001640744275339000980000000001&qu…

MyBatis:Parameter Maps collection does not contain value for 报错解决收录

MyBatis&#xff1a;Parameter Maps collection does not contain value for 报错问题解决收录 1.报错收录 后端测试时偶然遇到的用mybatis生成好的mapper文件&#xff0c;报Result Maps collection does not contain value…的错误 2.报错分析 java.lang.ILledalAraumentEx…

必应bing国内广告开户首充和开户费是多少?

微软必应Bing作为国内领先的搜索引擎之一&#xff0c;其广告平台凭借其精准的投放、高效的数据分析和广泛的用户覆盖&#xff0c;已成为众多企业的首选。 根据最新政策&#xff0c;2024年必应Bing国内广告开户预充值金额设定为1万元人民币起。这一调整旨在确保广告主在账户初始…

【嵌入式DIY实例】-OLED显示DHT22传感器数据

OLED显示DHT22传感器数据 1、应用实例介绍 本次实例将演示如何在OLED中显示DHT22温度湿度传感器的数据。实例主要分两步来完成: DHT22传感器驱动,采集温度和湿度OLED驱动,显示采集到的温度值和湿度值。在前面的文章中,对OLED的应用和驱动做了介绍,请参考: ESP8266-Ardu…

1.Nginx上配置 HTTPS

1.安装 Nginx&#xff1a; 如果还没有安装 Nginx&#xff0c;可以使用包管理工具安装。例如&#xff0c;在 Ubuntu 上&#xff1a; sudo apt update sudo apt install nginx2.上传证书和私钥文件&#xff1a; 将你的证书文件和私钥文件上传到服务器上的某个目录&#xff0c;…

VBA宏指令写的方法突然不能用了

背景:项目组有个自动化测试项目,实在excel中利用VBA开发的;时间比较久远,我前面的哥们走后,这个软件一直在用,最近系统不知道是不是更新的缘故;有些代码除了问题; 先上源码: Dim Conn As Object, Rst As Object Dim sqlStr$ Dim str_start_SN$, str2$ str_start_SN …

python 线性回归模型

教材链接-3.2. 线性回归的从零开始实现 c实现 该博客仅用于记录一下自己的代码&#xff0c;可与c实现作为对照 from d2l import torch as d2l import torch import random # nn是神经网络的缩写 from torch import nn from torch.utils import data# 加载训练数据 # 加载训…

什么是网关,网关有哪些作用?

网关(Gateway)是在计算机网络中用于连接两个独立的网络的设备&#xff0c;它能够在两个不同协议的网络之间传递数据。在互联网中&#xff0c;网关是一个可以连接不同协议的网络的设备&#xff0c;比如说可以连接局域网和互联网&#xff0c;它可以把局域网 的内部网络地址转换成…

论文阅读--GLIP

把detection和phrase ground(对于给定的sentence&#xff0c;要定位其中提到的全部物体)这两个任务合起来变成统一框架&#xff0c;从而扩展数据来源&#xff0c;因为文本图像对的数据还是很好收集的 目标检测的loss是分类loss定位loss&#xff0c;它与phrase ground的定位los…

爬虫学习--11.MySQL数据库的基本操作(上)

MySQL数据库的基本操作 创建数据库 我们可以在登陆 MySQL 服务后&#xff0c;使用命令创建数据库&#xff0c;语法如下: CREATE DATABASE 数据库名; 显示所有的数据库 show databases; 删除数据库 使用普通用户登陆 MySQL 服务器&#xff0c;你可能需要特定的权限来创建或者删…

Docker部署Minio小记

概述 因为工作需要搭建对象存储的测试环境&#xff0c;故而使用Docker部署Minio&#xff0c;测试通过博文记录用以备忘 步骤 拉取镜像 docker pull minio/minio启动容器 docker run -p 9000:9000 -p 9090:9090 \--name minio \-d --restartalways \-e "MINIO_ACCESS_K…

内脏油脂是什么?如何减掉?

真想减的人&#xff0c;减胖是很容易的&#xff0c;但想要形体美又健康&#xff0c;还是得从减内脏油脂开始&#xff0c;那么&#xff0c;问题来了&#xff0c;什么是内脏油脂&#xff1f; 油脂它分部于身体的各个角落&#xff0c;四肢、腹部、腰、臀部、脸、脖子...等&#xf…

VUE3+TS+elementplus创建table,纯前端的table

一、前言 开始学习前端&#xff0c;直接从VUE3开始&#xff0c;从简单的创建表格开始。因为自己不是专业的程序员&#xff0c;编程主要是为了辅助自己的工作&#xff0c;提高工作效率&#xff0c;VUE的基础知识并不牢固&#xff0c;主要是为了快速上手&#xff0c;能够做出一些…

Kubernetes中 Requests 和 Limits 的初步理解

1 灵魂拷问 我们在使用 Kubernetes 时是否遇到以下情况&#xff1a; 你会不会部署负载的时候将 CPU requests/limits 设置得过低或过高&#xff1f;你会不会部署负载的时候将 内存 requests/limits 设置得过低或过高&#xff1f;又或者你根本不设置 requests/limits&#xff…

SVN创建项目分支

目录 背景调整目录结构常规目录结构当前现状目标 调整SVN目录调整目录结构创建项目分支 效果展示 背景 当前自己本地做项目的时候发现对SVN创建项目不规范&#xff0c;没有什么目录结构&#xff0c;趁着创建目录分支的契机&#xff0c;顺便调整下SVN服务器上的目录结构 调整目…

Stable Diffusion WebUI使用inpaint anything插件实现图片局部重绘

Inpaint Anything是一个强大的图像处理工具,它结合了SAM(Segment Anything Model)、图像修补模型(如LaMa)和AIGC模型(如Stable Diffusion)等先进技术,以实现图像中物体的移除、内容的填补以及场景的替换。无论是对图像中的任何元素进行编辑,还是对图像整体进行场景转换…

【Vue】Vue2使用ElementUI

目录 Element UI介绍特点Vue2使用Element安装引入ElementUI组件库 使用ElementUI用户注册列表展示其他 mint-ui介绍特点安装组件引入组件Mint-ui相关组件 Element UI 介绍 官网(基于 Vue 2.x ):https://element.eleme.cn/#/zh-CN ElementUI 是一个基于 Vue.js 的桌面端组件库…