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

SpEl表达式使用示例

在 SpEL 中,如果你想动态计算 #walk_speed * 0.8 并生成 JSON 字符串 {"speedExec": 8.0}(假设 walk_speed = 10),你可以使用以下方法:


方法 1:直接解析 JSON 字符串中的 SpEL 表达式

如果你的 JSON 字符串是固定的(如 "{\"speedExec\": #walk_speed*0.8}"),你可以:

  1. 提取 SpEL 表达式#walk_speed*0.8)。
  2. 计算它的值10 * 0.8 = 8.0)。
  3. 替换回 JSON
代码示例
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;import java.util.HashMap;
import java.util.Map;public class SpELJsonExample {private static final ExpressionParser spelParser = new SpelExpressionParser();public static void main(String[] args) {Map<String, Object> variables = new HashMap<>();variables.put("walk_speed", 10); // 假设 walk_speed = 10StandardEvaluationContext context = new StandardEvaluationContext();context.setVariables(variables);String jsonTemplate = "{\"speedExec\": #walk_speed*0.8}";// 提取 SpEL 表达式(#walk_speed*0.8)String spelExpression = jsonTemplate.substring(jsonTemplate.indexOf("#"),jsonTemplate.indexOf("}") - 1);// 计算 SpEL 表达式的值Expression exp = spelParser.parseExpression(spelExpression);Double result = exp.getValue(context, Double.class);// 替换 JSON 中的 SpEL 表达式为计算结果String finalJson = jsonTemplate.replace(spelExpression, result.toString());System.out.println(finalJson); // 输出: {"speedExec": 8.0}}
}

输出

{"speedExec": 8.0}

方法 2:使用 SpEL 直接构造 JSON(推荐)

如果 JSON 结构较简单,可以直接用 SpEL 构造整个 JSON 字符串:

String spelJson = "{'speedExec': #walk_speed * 0.8}"; // 注意:SpEL 允许单引号
Expression exp = spelParser.parseExpression(spelJson);
Map<String, Object> result = exp.getValue(context, Map.class);System.out.println(result); // 输出: {speedExec=8.0}
转换为标准 JSON 字符串

如果你想输出标准的 JSON 格式(如 {"speedExec": 8.0}),可以借助 JacksonGson

import com.fasterxml.jackson.databind.ObjectMapper;ObjectMapper mapper = new ObjectMapper();
String jsonOutput = mapper.writeValueAsString(result);
System.out.println(jsonOutput); // 输出: {"speedExec":8.0}

方法 3:动态替换 JSON 中的多个 SpEL 表达式

如果 JSON 中有多个 SpEL 表达式(如 {"a": #x, "b": #y+1}),可以用正则匹配替换:

import java.util.regex.*;private static String evaluateJson(String json, StandardEvaluationContext context) {Pattern pattern = Pattern.compile("#([^\\s\"'}]+)");Matcher matcher = pattern.matcher(json);StringBuffer output = new StringBuffer();while (matcher.find()) {String expr = matcher.group(); // 如 "#walk_speed*0.8"Object value = spelParser.parseExpression(expr).getValue(context);matcher.appendReplacement(output, value.toString());}matcher.appendTail(output);return output.toString();
}

使用示例

String json = "{\"speedExec\": #walk_speed*0.8, \"threshold\": #walk_speed/2}";
String result = evaluateJson(json, context);
System.out.println(result); // 输出: {"speedExec": 8.0, "threshold": 5.0}

总结

场景推荐方法
固定 JSON 结构直接提取 SpEL 计算后替换(方法 1)
动态构造 JSON用 SpEL 生成 Map 再转 JSON(方法 2)
复杂 JSON 含多个 SpEL正则匹配替换(方法 3)

完整示例

import com.alibaba.fastjson.JSONObject;
import com.hsrg.utils.utils.HsrgUtil;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;public class SpELTest {private static final ExpressionParser spelParser = new SpelExpressionParser();public static void main(String[] args) {Map report = new HashMap();report.put("walk_distance",350); // 测试值在300-450之间report.put("walk_speed",10);report.put("id","id替换");Calendar calendar = Calendar.getInstance();String startTime = HsrgUtil.formatDateToStr(calendar.getTime());report.put("startTime",startTime);calendar.add(Calendar.DATE,7);String endTime = HsrgUtil.formatDateToStr(calendar.getTime());report.put("endTime",endTime);report.put("patientId","patientId替换");report.put("personId","personId替换");report.put("org_root_name","org_root_name替换");String json = "{\"speedExec\": #walk_speed*0.8}";StandardEvaluationContext evalContext = new StandardEvaluationContext();evalContext.setVariables(report);// 验证条件1System.out.println(evaluateCondition("#walk_distance < 450 && #walk_distance >= 300", evalContext));String spelJson = "{\n" +"\t\"businessId\": #id,\n" +"\t\"endTime\": #end_time,\n" +"\t\"extendParam\": {\n" +"\t\t\"speedExec\": #walk_speed*0.8,\n" +"\t\t\"targetRr\": 0,\n" +"\t\t\"thrHight\": 0,\n" +"\t\t\"thrLow\": 0,\n" +"\t\t\"thrType\": 5,\n" +"\t\t\"timeExec\": 20,\n" +"\t\t\"timeReady\": 5,\n" +"\t\t\"timeRecovery\": 5,\n" +"\t\t\"trainingMode\": \"speedMode\",\n" +"\t\t\"vegetable\": 0.0\n" +"\t},\n" +"\t\"frequency\": 3.0,\n" +"\t\"frequencyUnit\": \"周\",\n" +"\t\"item\": \"hurry\",\n" +"\t\"itemName\": \"快走\",\n" +"\t\"orgId\": #orgId,\n" +"\t\"parentItem\": \"aerobics\",\n" +"\t\"parentItemName\": \"有氧运动\",\n" +"\t\"patientId\": #patientId,\n" +"\t\"personId\": #personId,\n" +"\t\"recipelCycle\": 1.0,\n" +"\t\"recording\": 0,\n" +"\t\"rootOrgId\": #org_root_name,\n" +"\t\"source\": \"recipel\",\n" +"\t\"startTime\": #start_time,\n" +"\t\"status\": \"create\",\n" +"\t\"times\": 3\n" +"}"; // 注意:SpEL 允许单引号Expression exp = spelParser.parseExpression(spelJson);Map<String, Object> result = exp.getValue(evalContext, Map.class);System.out.println(JSONObject.toJSONString(result)); // 输出: {speedExec=8.0}}private static boolean evaluateCondition(String condition, StandardEvaluationContext context) {try {Expression exp = spelParser.parseExpression(condition);Boolean result = exp.getValue(context, Boolean.class);return result != null && result;} catch (Exception e) {throw new RuntimeException("SpEL evaluation failed for condition: " + condition, e);}}
}

输出结果

true
{"businessId":"id替换","extendParam":{"speedExec":8.0,"targetRr":0,"thrHight":0,"thrLow":0,"thrType":5,"timeExec":20,"timeReady":5,"timeRecovery":5,"trainingMode":"speedMode","vegetable":0.0},"frequency":3.0,"frequencyUnit":"周","item":"hurry","itemName":"快走","orgId":"#orgId","parentItem":"aerobics","parentItemName":"有氧运动","patientId":"patientId替换","personId":"personId替换","recipelCycle":1.0,"recording":0,"rootOrgId":"org_root_name替换","source":"recipel","status":"create","times":3}

SpEL表达式高级用法示例

SpEL支持丰富的表达式语法(以下写法仅支持设置根对象,如果是setVariables()需要按照完整示例的做修改):

// 1. 基本运算
"walkDistance * walkSpeed > 1000"// 2. 正则匹配
"orgId matches 'org\\d+'"// 3. 集合操作
"someList.?[#this > 10]"// 4. 安全导航
"someObject?.someProperty"// 5. 调用方法
"T(java.lang.Math).random() * 100.0"// 6. 复杂条件组合
"(walkDistance < 300 && walkSpeed > 4) || orgId == 'special'"

此语法需要修改,这种写法需要使用如下代码(设置根对象),此方法验证是失败的,或许我写的不对。

public static void main(String[] args) {Map report = new HashMap();report.put("walk_distance", 350);StandardEvaluationContext evalContext = new StandardEvaluationContext(report); // 设置根对象// 现在可以直接使用属性名访问System.out.println(evaluateCondition("walk_distance < 450 && walk_distance >= 300", evalContext));
}
http://www.xdnf.cn/news/1475.html

相关文章:

  • 简洁版C++类说明
  • 第四章:任务工作流编排
  • C语言 ——— 分支循环语句
  • Redis 主从复制
  • Codeforces Round 998 (Div. 3) ABCD
  • 深度解析 Java 中的 `computeIfAbsent`:原理、最佳实践与高级用法
  • Leetcode98、230:二叉搜索树——递归学习
  • 第12章:MCP服务端项目开发实战:数据持久化
  • React Ref引用机制解析
  • 文档构建:Sphinx全面使用指南 — 进阶篇
  • Axure中继器表格:实现复杂交互设计的利器
  • Linux磁盘管理
  • QT项目----电子相册(4)
  • 单片机通讯外设 (UART)、I2C、SPI、CAN 和 LIN 时序分析 使用场景以及优缺点对比分析报告
  • stm32之GPIO函数详解和上机实验
  • Spring Boot中的监视器:Actuator的原理、功能与应用
  • 基于PySide6与CATIA的直齿圆柱齿轮参数化建模系统开发实践
  • 湖南大学-操作系统实验四
  • 将天气查询API封装为MCP服务
  • godot源码编译
  • 【AI News | 20250423】每日AI进展
  • 数据库-基本概述 和 SQL 语言
  • SQL进阶知识:五、存储过程和函数
  • JAVA并发根源问题的讨论与思考
  • 2024沈阳区域赛,D - Dot Product Game
  • Visual Studio2022 配置 SDL3及拓展库
  • 从一个简单的HelloWorld来完整介绍Java的类加载过程
  • Python——流程控制
  • 代码分享:python实现svg图片转换为png和gif
  • linux软硬连接