jquick Path:让JSON数据处理像呼吸一样简单

作为每天和接口打交道的开发者,你是否也遇到过这种情况:面对嵌套了七八层的 JSON 响应,为了取一个price字段,不得不写一堆getJSONObject()for循环,代码冗长又容易出错?

直到我用上了jquickpath------ 这款被称为 "JSON 解析瑞士军刀" 的工具,才发现处理 JSON 原来可以这么优雅。今天就带大家全方位解锁这个效率神器!

先上关键信息:Maven 坐标

直接在pom.xml引入依赖,5 分钟就能跑通第一个示例:

xml

xml 复制代码
<dependency>
    <groupId>io.github.paohaijiao</groupId>
    <artifactId>jquick-path</artifactId>
    <version>最新版本请查看GitHub发布页</version>
</dependency>

最新版本获取:github.com/paohaijiao/...

8 个高频场景实战:一行代码解决问题

场景 1:提取深层嵌套字段(最常用)

需求 :从接口返回的 JSON 中,提取所有书籍的标题(嵌套在store->books数组中)

json

json 复制代码
{
  "store": {
    "books": [
      {"title": "Java编程思想", "price": 108},
      {"title": "深入理解Java虚拟机", "price": 99}
    ]
  }
}

传统做法 :需要先获取store对象,再获取books数组,然后循环遍历每个元素取title,至少 5 行代码。

jquickpath 实现

java

运行

javascript 复制代码
// 路径表达式:$.store.books.title
JSONPathResult result = JSONPathQueryBuilder.from(jsonData)
    .path("$.store.books.title")
    .execute();
// 结果:["Java编程思想", "深入理解Java虚拟机"]

场景 2:递归提取所有符合条件的字段

需求 :JSON 中有多个层级的price字段(可能在booksmagazines中),需要一次性提取所有价格。

json

json 复制代码
{
  "store": {
    "books": [{"price": 108}, {"price": 99}],
    "magazines": [{"price": 20}, {"price": 15}]
  }
}

jquickpath 实现

java

运行

javascript 复制代码
// 递归下降语法:.. 匹配所有子节点
JSONPathResult result = JSONPathQueryBuilder.from(jsonData)
    .path("$.store..price")
    .execute();
// 结果:[108, 99, 20, 15]

场景 3:数组切片与范围选择

需求:获取数组中第 2 到第 4 个元素(支持正向 / 反向索引)

json

json 复制代码
{
  "list": ["A", "B", "C", "D", "E"]
}

jquickpath 实现

java

运行

lua 复制代码
// 切片语法:[start:end:step]
JSONPathResult result1 = JSONPathQueryBuilder.from(jsonData)
    .path("$.list[1:4]") // 索引1到3(左闭右开)
    .execute(); // 结果:["B", "C", "D"]

// 倒序取最后2个
JSONPathResult result2 = JSONPathQueryBuilder.from(jsonData)
    .path("$.list[-2:]")
    .execute(); // 结果:["D", "E"]

场景 4:多条件过滤数据

需求 :筛选出价格大于 50 且有isbn编号的书籍

json

json 复制代码
{
  "books": [
    {"title": "Book1", "price": 60, "isbn": "123"},
    {"title": "Book2", "price": 40, "isbn": "456"},
    {"title": "Book3", "price": 70}
  ]
}

jquickpath 实现

java

运行

lua 复制代码
// 过滤表达式:?() 中使用逻辑运算符
JSONPathResult result = JSONPathQueryBuilder.from(jsonData)
    .path("$.books[?(@.price>50 && @.isbn)]")
    .execute();
// 结果:[{"title":"Book1", "price":60, "isbn":"123"}]

场景 5:用表达式计算数组下标

需求:获取数组的最后一个元素(动态计算下标)

json

json 复制代码
{
  "items": ["first", "second", "third"]
}

jquickpath 实现

java

运行

javascript 复制代码
// 表达式下标:使用 @.length() 获取数组长度length 是JEvaluator中内置的方法,更多函数请移步Javelin 项目
JSONPathResult result = JSONPathQueryBuilder.from(jsonData)
    .path("$.items[(@.length())-1]")
    .execute();
// 结果:"third"

场景 6:通配符匹配所有字段

需求:获取对象中所有子字段的值(无需知道字段名)

json

json 复制代码
{
  "user": {
    "name": "张三",
    "age": 25,
    "gender": "男"
  }
}

jquickpath 实现

java

运行

javascript 复制代码
// 通配符 * 匹配所有属性
JSONPathResult result = JSONPathQueryBuilder.from(jsonData)
    .path("$.user.*")
    .execute();
// 结果:["张三", 25, "男"]

场景 7:字符串字面量下标访问

需求:访问包含特殊字符的字段名(如带空格的字段)

json

json 复制代码
{
  "data": {
    "user name": "李四",
    "user age": 30
  }
}

jquickpath 实现

java

运行

javascript 复制代码
// 字符串字面量下标:用单引号包裹特殊字段名
JSONPathResult result = JSONPathQueryBuilder.from(jsonData)
    .path("$.data['user name']")
    .execute();
// 结果:"李四"

场景 8:取反逻辑筛选

需求 :筛选出没有isbn编号的书籍

json

json 复制代码
{
  "books": [
    {"title": "Book1", "isbn": "123"},
    {"title": "Book2"},
    {"title": "Book3"}
  ]
}

jquickpath 实现

java

运行

lua 复制代码
// 取反表达式:! 符号
JSONPathResult result = JSONPathQueryBuilder.from(jsonData)
    .path("$.books[?(!@.isbn)]")
    .execute();
// 结果:[{"title":"Book2"}, {"title":"Book3"}]

插件函数扩展指南

quickpath 支持通过插件函数扩展功能,基于 JEvaluator 组件实现函数的注册与调用。插件函数分为内置函数 (框架预定义)和自定义函数 (用户按需扩展),可用于数据处理、类型转换、逻辑计算等场景。用法可参考场景5中用表达式计算数组下标中的内置方法length

一、内置插件函数

JEvaluator 已内置多种常用函数,覆盖类型转换、数学运算、字符串处理、日期操作等场景,可直接调用。

1. 类型转换函数

  • toInteger:转换为整数。入参为待转换的数字或字符串。示例:evaluateFunction("toInteger", Arrays.asList("123")) 返回 123
  • toDouble:转换为双精度浮点数。入参为待转换的数字或字符串。示例:evaluateFunction("toDouble", Arrays.asList("3.14")) 返回 3.14
  • parseToDate:将字符串解析为日期。入参为日期字符串和格式字符串。示例:evaluateFunction("parseToDate", Arrays.asList("2023-01-01", "yyyy-MM-dd")) 返回 Date 对象。
  • toFloat:转换为单精度浮点数。入参为待转换的数字或字符串。示例:evaluateFunction("toFloat", Arrays.asList(1.5)) 可完成相应转换。
  • toString:转换为字符串。入参为任意可转换为字符串的对象。示例:evaluateFunction("toString", Arrays.asList(1.5)) 返回 "1.5"

2. 数学函数

  • sum:计算多个数字的和。入参为可变长度的数字列表。示例:evaluateFunction("sum", Arrays.asList(1, 2, 3)) 返回 6
  • max:求最大值。入参为可变长度的数字列表。示例:evaluateFunction("max", Arrays.asList(1, 5, 3)) 返回 5
  • min:求最小值。入参为可变长度的数字列表。示例:evaluateFunction("min", Arrays.asList(1, 5, 3)) 返回 1
  • avg:求平均值。入参为可变长度的数字列表。示例:evaluateFunction("avg", Arrays.asList(1, 2, 3, 4, 5)) 返回 3.0
  • round:四舍五入保留指定精度。入参为数字和保留小数位数。示例:evaluateFunction("round", Arrays.asList(3.1415, 2)) 返回 3.14
  • ceil:向上取整。入参为数字。示例:evaluateFunction("ceil", Arrays.asList(1.5)) 返回 2.0
  • floor:向下取整。入参为数字。示例:evaluateFunction("floor", Arrays.asList(1.5)) 返回 1.0

3. 字符串函数

  • toLower:将字符串转为小写。入参为字符串。示例:evaluateFunction("toLower", Arrays.asList("HELLO")) 返回 "hello"
  • toUpper:将字符串转为大写。入参为字符串。示例:evaluateFunction("toUpper", Arrays.asList("hello")) 返回 "HELLO"
  • join:拼接列表元素。入参为列表和分隔符。示例:evaluateFunction("join", Arrays.asList(Arrays.asList("a", "b"), ",")) 返回 "a,b"
  • split:按分隔符拆分字符串。入参为字符串和分隔符。示例:evaluateFunction("split", Arrays.asList("123,12344", ",")) 返回包含拆分后元素的列表。
  • substring:截取子字符串。入参为原字符串、起始索引和长度。示例:evaluateFunction("substring", Arrays.asList("substring", 1, 3)) 返回 "ub"
  • replace:替换字符串内容。入参为原字符串、目标子串和替换子串。示例:evaluateFunction("replace", Arrays.asList("abc", "a", "x")) 返回 "xbc"
  • contains:判断字符串是否包含子串。入参为原字符串和子串。示例:evaluateFunction("contains", Arrays.asList("Hello World", "Hello")) 返回 true
  • startsWith:判断字符串是否以指定前缀开头。入参为原字符串和前缀。示例:evaluateFunction("startsWith", Arrays.asList("Hello World", "Hel")) 返回 true
  • endsWith:判断字符串是否以指定后缀结尾。入参为原字符串和后缀。示例:evaluateFunction("endsWith", Arrays.asList("Hello World", "World")) 返回 true
  • length:获取字符串、列表或数组的长度。入参为字符串、列表或数组。示例:evaluateFunction("length", Arrays.asList("Hello World")) 返回 11

4. 日期函数

  • dateFormat:对日期进行格式化。入参为 Date 对象和格式字符串。示例:evaluateFunction("dateFormat", Arrays.asList(new Date(), "yyyy-MM-dd")) 返回 "2023-10-01"

5. 集合函数

  • trans:根据上下文参数进行转换。入参为上下文参数和键。示例:JContext contextParams = new JContext(); contextParams.put("1","男"); evaluateFunction("trans", Arrays.asList(contextParams, "1")) 返回 "男"

二、自定义插件函数

若内置函数无法满足需求,可通过 JEvaluator.registerFunction 方法注册自定义函数,支持 Function(单参数)、BiFunction(双参数)或多参数函数(通过 List<Object> 接收参数)。

1. 注册与调用流程

步骤 1:定义函数实现

根据参数数量选择函数接口:

  • 单参数:使用 Function<Object, Object>
  • 双参数:使用 BiFunction<Object, Object, Object>
  • 多参数:使用 Function<List<Object>, Object>(通过列表接收所有参数)
步骤 2:注册函数

通过 JEvaluator.registerFunction(String functionName, Object function) 注册函数,例如:

java

运行

javascript 复制代码
// 注册双参数函数:计算两个日期相差的天数
JEvaluator.registerFunction("daysBetween", (BiFunction<Object, Object, Object>) (date1, date2) -> {
    long diff = ((Date) date2).getTime() - ((Date) date1).getTime();
    return TimeUnit.DAYS.convert(diff, TimeUnit.MILLISECONDS);
});

// 注册多参数函数:计算多个数字的乘积
JEvaluator.registerFunction("multiply", (Function<List<Object>, Object>) args -> {
    double result = 1;
    for (Object arg : args) {
        result *= ((Number) arg).doubleValue();
    }
    return result;
});
步骤 3:调用自定义函数

通过 JEvaluator.evaluateFunction(String functionName, List<Object> args) 调用,例如:

java

运行

ini 复制代码
// 调用 daysBetween 函数
Date today = new Date();
Date nextWeek = new Date(today.getTime() + 7 * 24 * 60 * 60 * 1000);
Object dayDiff = JEvaluator.evaluateFunction("daysBetween", Arrays.asList(today, nextWeek));
System.out.println(dayDiff); // 输出:7

// 调用 multiply 函数
Object product = JEvaluator.evaluateFunction("multiply", Arrays.asList(2, 3, 4));
System.out.println(product); // 输出:24

为什么选择 jquickpath?

用过其他 JSON 解析工具的同学可能会问:市面上类似的库不少,jquickpath 有什么特别之处?

  1. 语法更全面 :支持递归下降(..)、表达式下标、多条件过滤等高级特性,覆盖 90%+ 实际场景
  2. API 更直观:链式调用设计,无论是用字符串路径还是 Java API 构建路径,都能保持代码简洁
  3. 兼容性更强:无缝对接 JSON 字符串、JSONObject、JSONArray 等常见格式
  4. 性能更优异:底层做了表达式预编译和缓存优化,大数据量解析也不卡顿

最后说句掏心窝的话

自从用了 jquickpath,我处理 JSON 的代码量至少减少了 60%,调试时间也大幅缩短。最爽的是,面对产品经理临时变更的字段提取需求,我再也不用改一堆代码,只需要调整一下路径表达式就行。

如果你也经常跟复杂 JSON 打交道,真心建议试试这个工具 ------ 毕竟,谁不想少写代码早下班呢?

👉 官网地址:github.com/paohaijiao/...(含完整语法文档和更多示例)

觉得有用的话,别忘了点赞收藏,下次处理 JSON 时就能立马用上啦~

相关推荐
B1118521Y463 小时前
flask的使用
后端·python·flask
xuxie134 小时前
SpringBoot文件下载(多文件以zip形式,单文件格式不变)
java·spring boot·后端
重生成为编程大王5 小时前
Java中的多态有什么用?
java·后端
Funcy6 小时前
XxlJob 源码分析03:执行器启动流程
后端
豌豆花下猫7 小时前
Python 潮流周刊#118:Python 异步为何不够流行?(摘要)
后端·python·ai
秋难降8 小时前
SQL 索引突然 “罢工”?快来看看为什么
数据库·后端·sql
Access开发易登软件9 小时前
Access开发导出PDF的N种姿势,你get了吗?
后端·低代码·pdf·excel·vba·access·access开发
中国胖子风清扬10 小时前
Rust 序列化技术全解析:从基础到实战
开发语言·c++·spring boot·vscode·后端·中间件·rust
bobz96510 小时前
分析 docker.service 和 docker.socket 这两个服务各自的作用
后端
野犬寒鸦10 小时前
力扣hot100:旋转图像(48)(详细图解以及核心思路剖析)
java·数据结构·后端·算法·leetcode