当前位置: 首页 > news >正文

java + groovy : 动态解析groovy脚本,并与java交互

这是一个在String变量中的内容:
"if (loanAmount> 100000 && creditScore < 700) { riskLevel = 'High' }"
使用 groovy 结合 java ,写一个动态解析上述变量并执行逻辑的demo

以下是一个使用 Groovy 结合 Java 来动态解析你提供的字符串变量中的规则并执行逻辑的示例代码,示例基于 Java 的ScriptEngine接口以及 Groovy 的相关功能来实现:

1. Java 代码部分(包含主类用于测试)

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;public class GroovyRuleExecutionDemo {public static void main(String[] args) {// 模拟业务数据double loanAmount = 120000;int creditScore = 650;// 规则字符串,这里对应你给定的内容String rule = "if (loanAmount > 100000 && creditScore < 700) { riskLevel = 'High' }";// 调用方法执行规则解析与逻辑判断try {String result = executeRule(rule, loanAmount, creditScore);System.out.println("风险评估结果: " + result);} catch (ScriptException e) {System.err.println("执行规则时出现错误: " + e.getMessage());}}public static String executeRule(String rule, double loanAmount, int creditScore) throws ScriptException {ScriptEngineManager manager = new ScriptEngineManager();ScriptEngine engine = manager.getEngineByName("groovy");// 将业务数据设置到脚本引擎的上下文中engine.put("loanAmount", loanAmount);engine.put("creditScore", creditScore);engine.put("riskLevel", "Low");// 执行规则脚本engine.eval(rule);return (String) engine.get("riskLevel");}
}

2. 代码解释

  • 在main方法中:
    • 首先模拟了业务数据,即loanAmount(贷款金额)和creditScore(信用评分)的值。
    • 然后定义了包含业务规则的字符串变量rule,其内容就是你提供的规则语句。
    • 最后调用executeRule方法,并传入规则字符串以及业务数据,获取风险评估结果并打印输出,如果执行过程中出现ScriptException异常,则打印错误信息。
  • 在executeRule方法中:
    • 通过ScriptEngineManager获取一个名为groovy的ScriptEngine实例,用于执行 Groovy 脚本。
    • 将业务数据(loanAmount、creditScore)以及初始风险等级(默认为Low)设置到脚本引擎的上下文中,这样在规则脚本中就可以访问和使用这些变量了。
    • 使用engine.eval(rule)执行规则脚本,也就是解析并执行传入的规则字符串中的逻辑判断。
    • 最后从脚本引擎的上下文中获取riskLevel变量的值作为风险评估结果返回。

这个示例展示了如何在 Java 代码中利用 Groovy 的脚本执行能力,动态地解析和执行包含在字符串变量中的业务规则逻辑。在实际应用场景中,你可以从配置文件、数据库等地方获取规则字符串,并且可以根据业务需求灵活扩展,比如添加更多的业务变量、更复杂的规则逻辑等。

请注意,在实际项目中,为了更好的安全性和稳定性,可能需要对从外部获取的规则字符串进行更严格的校验和处理,避免出现恶意脚本注入等安全问题。

在上面的例子中,rule 字符串里的内容必须是 groovy 的脚本语言吗?

是的,在上述例子中,rule字符串里的内容必须遵循 Groovy 脚本语言的语法规范。

原因在于示例中利用了 Groovy 的脚本引擎来解析和执行这段字符串内容,引擎会按照 Groovy 语言既定的语法规则去识别其中的变量、表达式、语句结构等元素,进而进行相应的运算和逻辑判断。

例如,像定义变量(如示例中riskLevel变量的赋值操作)、条件判断(if语句的写法及条件表达式的语法)等都是依照 Groovy 的语法要求来编写的。如果写成不符合 Groovy 语法的内容,比如写成类似 Python 语法的语句 “if loanAmount> 100000 and creditScore < 700: riskLevel = 'High'”(这里使用了 Python 的 and 逻辑连接词等 Python 语法元素),在执行时,Groovy 脚本引擎就无法正确解析,会抛出 ScriptException 异常,提示语法错误相关的信息。

不过,从灵活性角度来看,可以根据实际业务需求,以 Groovy 语法为基础去动态构造各种复杂或简单的规则脚本内容放在这个rule字符串中,只要符合 Groovy 语法就能被正确解析和执行,实现业务规则的动态化运用。

rule字符串中的groovy脚本可以调用外部的java 代码吗?

在 Groovy 脚本中是可以调用外部的 Java 代码的呀,在上述的例子中,如果有对应的 Java 类和方法,有以下几种常见的调用方式:

静态导入 Java 类和方法

如果 Java 代码中有静态方法或常量等可以被静态导入,在 Groovy 脚本中可以像下面这样使用:

假设在 Java 中有一个工具类 MathUtils ,其中有一个静态方法 double round(double num) 用于对数字进行四舍五入。

在 Groovy 脚本中可以这样调用:

import static com.example.MathUtils.roundif (loanAmount > 100000 && creditScore < 700) {riskLevel = 'High'// 调用Java静态方法def roundedLoanAmount = round(loanAmount)println("四舍五入后的贷款金额: ${roundedLoanAmount}")
}

创建 Java 类实例并调用方法

如果 Java 代码中有非静态的类和方法,在 Groovy 脚本中可以创建实例并调用方法,例如,假设 Java 中有一个 LoanCalculator 类,其中有一个方法 double calculateInterest(double loanAmount) 用于计算贷款利息。

在 Groovy 脚本中可以这样调用:

import com.example.LoanCalculatorif (loanAmount > 100000 && creditScore < 700) {riskLevel = 'High'// 创建Java类实例并调用方法def calculator = new LoanCalculator()def interest = calculator.calculateInterest(loanAmount)println("贷款利息: ${interest}")
}

通过脚本引擎上下文传递 Java 对象

在 Java 代码中执行 Groovy 脚本时,可以将 Java 对象通过脚本引擎的上下文传递给 Groovy 脚本,然后在脚本中直接使用。

例如,在 Java 代码中有一个 LoanDetails 对象,包含了更多贷款相关的详细信息,在执行 Groovy 脚本前将其传递到脚本引擎上下文中:

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;public class GroovyRuleExecutionDemo {public static void main(String[] args) {// 模拟业务数据double loanAmount = 120000;int creditScore = 650;// 规则字符串,这里对应你给定的内容String rule = "if (loanAmount > 100000 && creditScore < 700) { riskLevel = 'High'; printLoanDetails(loanDetails) }";// 创建一个LoanDetails对象LoanDetails loanDetails = new LoanDetails(loanAmount, creditScore, "Personal Loan");// 调用方法执行规则解析与逻辑判断try {String result = executeRule(rule, loanDetails);System.out.println("风险评估结果: " + result);} catch (ScriptException e) {System.err.println("执行规则时出现错误: " + e.getMessage());}}public static String executeRule(String rule, LoanDetails loanDetails) throws ScriptException {ScriptEngineManager manager = new ScriptEngineManager();ScriptEngine engine = manager.getEngineByName("groovy");// 将业务数据和LoanDetails对象设置到脚本引擎的上下文中engine.put("loanAmount", loanDetails.getLoanAmount());engine.put("creditScore", loanDetails.getCreditScore());engine.put("riskLevel", "Low");engine.put("loanDetails", loanDetails);// 执行规则脚本engine.eval(rule);return (String) engine.get("riskLevel");}
}

在 Groovy 脚本中可以直接使用传递进来的 loanDetails 对象:

if (loanAmount > 100000 && creditScore < 700) {riskLevel = 'High'// 直接使用传递进来的Java对象printLoanDetails(loanDetails)
}// 定义一个在脚本中调用的方法,用于打印LoanDetails对象的信息
def printLoanDetails(LoanDetails loanDetails) {println("贷款类型: ${loanDetails.getLoanType()}")println("贷款金额: ${loanDetails.getLoanAmount()}")println("信用评分: ${loanDetails.getCreditScore()}")
}

所以,在rule字符串中的 Groovy 脚本是可以调用外部的 Java 代码的,通过上述几种方式可以实现 Groovy 脚本与 Java 代码之间的交互和协同工作,从而更好地利用已有的 Java 代码资源来满足业务规则的编写和执行需求。需要注意的是,在实际应用中要确保 Java 类和方法的可见性以及传递的对象的合法性等。

可以在java中调用在 groovy 的 rule脚本中定义的方法吗?

在 Java 中可以调用 Groovy 的 rule 脚本中定义的方法,以下是一种常见的实现方式:

1. 编写 Groovy 脚本

首先,编写包含方法定义的 Groovy 脚本,例如创建一个名为 ruleScript.groovy 的文件,内容如下:

// 定义一个方法用于计算两个数的和
def addNumbers(int num1, int num2) {return num1 + num2
}// 定义一个方法用于判断一个数是否为偶数
def isEven(int num) {return num % 2 == 0
}

2. 在 Java 中调用 Groovy 脚本中的方法

在 Java 代码中,可以使用 ScriptEngine 来执行 Groovy 脚本并调用其中定义的方法,示例代码如下:

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import java.util.Arrays;public class JavaCallGroovyMethod {public static void main(String[] args) {try {// 创建ScriptEngineManager并获取Groovy脚本引擎ScriptEngineManager manager = new ScriptEngineManager();ScriptEngine engine = manager.getEngineByName("groovy");// 执行Groovy脚本engine.eval(new java.io.FileReader("ruleScript.groovy"));// 调用Groovy脚本中定义的addNumbers方法Object result1 = engine.invokeFunction("addNumbers", 5, 3);System.out.println("5 + 3 = " + result1);// 调用Groovy脚本中定义的isEven方法Object result2 = engine.invokeFunction("isEven", 6);System.out.println("6 is even? " + result2);// 调用Groovy脚本中定义的isEven方法Object result3 = engine.invokeFunction("isEven", 7);System.out.println("7 is even? " + result3);} catch (ScriptException | NoSuchMethodException e) {e.printStackTrace();}}
}

在上述示例中:

  • 首先通过 ScriptEngineManager 获取 Groovy 脚本引擎。
  • 然后使用 engine.eval 执行 Groovy 脚本文件 ruleScript.groovy ,使得脚本中的方法被加载到脚本引擎中。
  • 最后通过 engine.invokeFunction 分别调用了 Groovy 脚本中定义的 addNumbers 和 isEven 方法,并将结果打印输出。

需要注意的是,在实际应用中,可能需要根据具体情况对脚本的执行和方法调用进行更多的错误处理和优化,比如处理脚本执行失败、方法不存在等情况,以及对传递的参数和返回结果进行更严格的类型检查和转换等。同时,如果 Groovy 脚本中的方法依赖于特定的上下文或变量,还需要在 Java 代码中正确地设置和传递这些上下文信息。

最后编辑于:2025-06-15 10:04:52


喜欢的朋友记得点赞、收藏、关注哦!!!

http://www.dtcms.com/a/277750.html

相关文章:

  • MacBook Air M4 安装 VMware Fusion Pro
  • 问题记录:Fastjson序列化-空值字段处理
  • CA复习功课
  • Appdynamic 配置 PostgreSQL 收集器
  • 复习笔记 34
  • 【VSCode+LaTeX】科研写作环境搭建
  • 内存池(C++)v3 | 简历写法 | 相关面试题
  • 浏览器本地存储——使用localStorage实现电商系统商品收藏功能实战
  • 在网站学装机
  • SCTP协议网络编程
  • 从源码看Nginx:Nginx事件驱动架构深度拆解来了
  • linux上的软挂载操作方法
  • Docker 快速上手
  • 【elementUI踩坑记录】解决 el-table 固定列 el-table__fixed 导致部分滚动条无法拖动的问题
  • 全星质量管理QMS软件系统——汽车零部件制造业数字化转型的质量管理中枢
  • 【设计模式】备忘录模式(标记(Token)模式)
  • 设计模式:软件开发的高效解决方案(单例、工厂、适配器、代理)
  • 从 Intel MacBook 迁移到 ARM MacBook 的完整指南
  • Cursor的使用
  • Pandas 中 stack 和 unstack 方法在数据重塑中的应用
  • 日记-生活随想
  • 信号量机制,互斥的避免自旋锁的实现方法(操作系统)
  • SQL141 试卷完成数同比2020年的增长率及排名变化
  • 《棒球知识科普》体育健将有什么特点·棒球1号位
  • SQL155 大小写混乱时的筛选统计
  • C++进阶-二叉搜索树(二叉排序树)
  • Java机密计算实战:Intel SGX与Spring机密数据保护
  • 在Linux服务器上通过screen挂起程序,以及利用reptyr从终端剥夺程序的控制权转交screen的方法
  • 【Python类管理】装饰器@的实际用法和查询
  • QML 自定义Model基础之QAbstractListModel