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 时就能立马用上啦~

相关推荐
Moonbit1 小时前
MoonBit 作者寄语 2025 级清华深圳新生
前端·后端·程序员
前端的阶梯1 小时前
开发一个支持支付功能的微信小程序的注意事项,含泪送上
前端·后端·全栈
咕噜分发企业签名APP加固彭于晏1 小时前
腾讯元器的优点是什么
前端·后端
AAA修煤气灶刘哥2 小时前
Swagger 用着糟心?试试 Knife4j,后端开发狂喜
后端·面试
bobz9652 小时前
MCP on windows
后端
泡海椒2 小时前
jquickexcel 全功能指南:从数据导入到精美导出的完整流程
后端
iOS开发上架哦3 小时前
移动端网页调试实战,键盘弹出与视口错位问题的定位与优化
后端
百度Geek说3 小时前
PaddleMIX推出扩散模型推理加速Fast-Diffusers:自研蒸馏加速方法FLUX-Lightning实现4步图像生成
后端
gopher_looklook3 小时前
Go并发实战:singleflight 源码解读与二次封装
数据结构·后端·go
用户833810251223 小时前
我为什么做PmMock:让接口设计不再头疼
前端·后端