Java JQuick-Path 实战手册:根对象、递归下降、通配符,一篇全掌握

简介: Java开发者还在为JSON取值反复判空、层层嵌套而烦恼?jquick-path四大核心语法——根对象($)、属性访问(.)、递归下降(..)、通配符(*),一次讲透!轻量易用,支持path字符串与Java链式调用,大幅提升JSON解析效率。开源地址:github.com/paohaijiao/jquick-path

Java JSONPath 语法不会用?jquick-path 四大核心语法实战:根对象、属性访问、递归下降、通配符一次讲透

还在为复杂 JSON 一层层取值、反复判空而烦恼?本文从实际开发角度出发,带你掌握 jquick-path 最常用的四类核心语法,并分别给出 path 路径表达式和 Java 便捷访问方式。

Git 地址

https://github.com/paohaijiao/jquick-path

Maven 坐标

<dependency>
  <groupId>io.github.paohaijiao</groupId>
  <artifactId>jquick-path</artifactId>
  <version>最新版本</version>
</dependency>

一、为什么需要 jquick-path?

在 Java 后端开发中,JSON 几乎无处不在:

  • 微服务接口之间使用 JSON 传输数据;
  • 第三方 API 返回 JSON;
  • 配置中心和规则系统依赖 JSON;
  • 数据转换和接口聚合需要频繁提取 JSON 字段。

最初大家通常会直接手写取值逻辑,但随着 JSON 层级变深,代码很容易变成这样:

  • 一层层访问对象;
  • 一层层判断是否为空;
  • 遇到数组还要手动遍历;
  • 相同查询逻辑散落在多个业务类中。

这类代码短期可以运行,长期却会带来可读性差、重复代码多和维护成本高等问题。

jquick-path 的目标,就是把 JSON 数据访问抽象成更清晰的路径语法,让开发者能够用统一方式完成 JSON 查询。

本文只聚焦四个最常用、最值得掌握的核心语法:

  1. 根对象;
  2. 访问对象属性;
  3. 递归下降;
  4. 通配符。

掌握这四类语法,就能覆盖大量日常 JSON 数据提取场景。

二、准备一份示例 JSON

本文统一使用下面这份数据进行说明:

{
   
  "store": {
   
    "books": [
      {
   
        "title": "Book 1",
        "author": "Author 1",
        "price": 10
      },
      {
   
        "title": "Book 2",
        "author": "Author 2",
        "price": 15
      },
      {
   
        "title": "Book 3",
        "author": "Author 3",
        "price": 20
      }
    ]
  }
}

这份数据具备几个典型特点:

  • 顶层存在 store 对象;
  • store 下存在 books 数组;
  • 数组中的每个元素都是图书对象;
  • 图书对象包含 title、author、price 属性。

接下来所有案例都围绕这份数据展开。

三、先看四大语法速查表

语法 path 示例 作用
根对象 $.store 从 JSON 根节点开始查询
访问对象属性 $.store.books 逐层访问对象属性
递归下降 $.store.books..price 向下递归查找所有 price 属性
通配符 $.store.books.* 获取 books 数组中的全部元素
通配符属性 $.* 获取根对象下的所有属性

可以把这四类语法简单理解为:

  • 根对象:从哪里开始;
  • 对象属性:沿哪条路径走;
  • 递归下降:不确定层级时向下搜索;
  • 通配符:不指定具体名称或索引,批量匹配。

四、根对象语法:从 JSON 的起点开始查询

4.1 根对象是什么?

根对象表示整个 JSON 文档的起点。

在 path 表达式中,通常使用 $ 表示根节点。所有从完整 JSON 文档开始的查询,都可以从 $ 出发。

例如,查询顶层的 store 对象:

$.store

查询 store 下的 books 数组:

$.store.books

4.2 根据 path 路径查询

使用 path 方式时,可以直接把路径表达式传给查询构建器:

JSONPathQueryBuilder.from(jsonObject)
    .path("$.store.books")
    .limit(10)
    .execute();

这段代码表达的意思非常明确:

  1. 从 JSON 根对象开始;
  2. 进入 store 属性;
  3. 继续进入 books 属性;
  4. 执行查询并限制返回数量。

4.3 使用 Java 便捷方式查询根对象

如果你更喜欢在 Java 中显式构建路径,可以使用 JRoot.ROOT:

JSONPathQueryBuilder.from(jsonObject)
    .document(JPath.fromRoot(JRoot.ROOT)
        .property("store")
        .property("books"))
    .limit(10)
    .execute();

这里的 JRoot.ROOT 就表示从根对象开始,后面的 property 表示沿属性继续访问。

4.4 根对象语法适合什么场景?

根对象适合绝大多数固定结构 JSON 查询,例如:

  • 读取接口返回中的固定字段;
  • 读取配置文件中的指定节点;
  • 从完整 JSON 文档中获取业务数据;
  • 作为后续通配符和递归查询的起点。

从程序员角度看,根对象语法的价值在于:让查询入口保持明确。

五、访问对象属性:沿着 JSON 路径逐层取值

5.1 属性访问的基本写法

访问对象属性,是 JSONPath 使用频率最高的语法。

在 jquick-path 中,可以使用点号表达层级关系:

$.store.books

它表示:

  • $:根对象;
  • store:进入根对象的 store 属性;
  • books:进入 store 对象的 books 属性。

如果继续访问数组元素中的字段,路径还可以继续向后扩展:

$.store.books.title

在实际数组查询中,也可以配合下标或其他选择器访问具体元素。

5.2 根据 path 访问对象属性

JSONPathQueryBuilder.from(jsonObject)
    .path("$.store.books")
    .limit(10)
    .execute();

如果要访问指定图书的价格,可以使用类似下面的路径:

$.store.books[2].price

对应 Java 调用:

JSONPathQueryBuilder.from(jsonObject)
    .path("$.store.books[2].price")
    .limit(10)
    .execute();

这里的访问顺序是:

  1. 从根对象进入 store;
  2. 进入 books 数组;
  3. 获取索引为 2 的图书;
  4. 读取该图书的 price 属性。

5.3 使用 Java 便捷方式访问对象属性

使用 Java 链式方式时,可以连续调用 property:

JSONPathQueryBuilder.from(jsonObject)
    .document(JPath.fromRoot(JRoot.ROOT)
        .property("store")
        .property("books"))
    .limit(10)
    .execute();

如果需要继续访问某个数组元素的属性,可以在路径中追加对应的 segment:

JSONPathQueryBuilder.from(jsonObject)
    .document(JPath.fromRoot(JRoot.ROOT)
        .property("store")
        .property("books")
        .segment(JSegments.subscript(JIndexSubscript.of(2)))
        .property("price"))
    .limit(10)
    .execute();

这种写法的优势是路径结构在 Java 代码中非常清楚,适合:

  • 需要封装成公共方法的查询逻辑;
  • 需要和业务代码组合的场景;
  • 不希望在代码中到处散落完整字符串路径的场景。

5.4 点号和属性访问的工程价值

对象属性访问看起来简单,但它解决的是非常核心的工程问题:

  • 让 JSON 层级关系可以直接阅读;
  • 让数据访问逻辑从业务流程中独立出来;
  • 让复杂 JSON 的查询路径具备统一表达方式;
  • 让后续的通配符和递归语法可以自然组合。

可以说,根对象确定入口,属性访问负责搭建基本路径。

六、递归下降:不知道层级时,如何向下搜索?

6.1 递归下降解决什么问题?

在真实项目里,JSON 结构不一定永远规整。

你可能遇到这些情况:

  • 相同字段出现在不同层级;
  • 第三方接口版本变化导致嵌套层级不固定;
  • 只知道目标字段名,不想手动写完整路径;
  • 需要从一棵 JSON 对象树中搜索所有匹配字段。

如果使用传统写法,就需要自己递归遍历对象和数组。

递归下降语法就是为这类场景准备的。

6.2 根据 path 递归查找属性

在 path 表达式中,可以使用 .. 表示递归向下查找。

例如,从 store.books 下递归寻找所有 price 属性:

$.store.books..price

对应的 Java path 调用方式:

JSONPathQueryBuilder.from(jsonData)
    .path("$.store.books..price")
    .limit(10)
    .execute();

这个表达式的重点不是固定某一层,而是:

  • 先定位到 store.books;
  • 然后向下递归;
  • 找到所有名称为 price 的属性。

在示例数据中,最终可以得到所有图书的价格:

[10, 15, 20]

6.3 使用 Java 便捷方式递归查找属性

Java 方式可以使用 JSegments.recursiveId:

JSONPathQueryBuilder.from(jsonData)
    .document(JPath.fromRoot(JRoot.ROOT)
        .property("store")
        .property("books")
        .segment(JSegments.recursiveId("price")))
    .limit(10)
    .execute();

recursiveId("price") 表示递归寻找名为 price 的属性。

6.4 递归下降的使用建议

递归查询虽然方便,但也应该根据实际场景使用:

  • 目标字段名称明确时,递归查询更合适;
  • JSON 层级稳定时,优先使用明确路径;
  • 数据结构复杂或来源不统一时,递归下降能明显减少代码量;
  • 递归范围过大时,要注意查询数据量和执行成本。

从程序员角度看,递归下降最大的价值是:把手写递归遍历逻辑交给路径表达式处理。

七、通配符:不指定具体字段,批量匹配数据

7.1 通配符是什么?

通配符使用 * 表示。

它的含义是:不指定具体的属性名称或数组元素位置,而是匹配当前范围内的全部对象属性或数组元素。

通配符常用于两类场景:

  • 匹配一个对象下的所有属性;
  • 匹配一个数组中的所有元素。

7.2 根据 path 获取对象的全部属性

获取根对象下的所有属性:

$.*

对应 Java path 调用:

JSONPathQueryBuilder.from(jsonData)
    .path("$.*")
    .limit(10)
    .execute();

也可以继续从指定对象开始使用通配符:

$.store.*

它表示获取 store 对象下的所有属性。

7.3 使用 Java 便捷方式获取对象的全部属性

Java 便捷方式中,可以把 * 作为属性名称传给 property:

JSONPathQueryBuilder.from(jsonData)
    .document(JPath.fromRoot(JRoot.ROOT)
        .property("*"))
    .limit(10)
    .execute();

这就是 Java 写法和 path 写法的对应关系:

path 写法 Java 便捷写法
$.* .property("*")
$.store.* .property("store").property("*")

7.4 根据 path 获取数组全部元素

对于 books 数组,如果希望获取全部图书,可以使用:

$.store.books.*

对应 Java path 调用:

JSONPathQueryBuilder.from(jsonData)
    .path("$.store.books.*")
    .limit(10)
    .execute();

7.5 使用 Java 便捷方式获取数组全部元素

JSONPathQueryBuilder.from(jsonData)
    .document(JPath.fromRoot(JRoot.ROOT)
        .property("store")
        .property("books")
        .property("*"))
    .limit(10)
    .execute();

这个写法表示:

  1. 进入根对象的 store;
  2. 进入 books 数组;
  3. 使用通配符匹配数组中的所有元素。

7.6 通配符适合哪些业务场景?

通配符适合:

  • 批量读取列表数据;
  • 对同一类对象做统一转换;
  • 不关心数组具体索引的场景;
  • 动态结构 JSON 的快速扫描;
  • 配置和规则系统中的范围查询。

不过也要注意,通配符会扩大匹配范围。数据规模较大时,建议结合明确的前置路径和 limit 使用。

八、四类语法如何组合使用?

实际开发中,四类语法通常不是单独使用,而是组合起来使用。

例如:

$.store.books..price

这里同时使用了:

  • $:根对象;
  • .store.books:对象属性访问;
  • ..price:递归下降查找属性。

再比如:

$.store.books.*

这里组合了:

  • $:根对象;
  • .store.books:属性访问;
  • *:通配符获取全部数组元素。

这说明 jquick-path 的语法设计是组合式的。程序员不需要为每个新场景单独记忆一套 API,而是可以根据 JSON 结构逐步拼接查询路径。

九、path 和 Java 便捷方式怎么选?

9.1 优先使用 path 的场景

如果查询规则需要:

  • 放入配置文件;
  • 动态传入;
  • 由规则系统管理;
  • 快速表达和修改;

建议优先选择 path 方式。

例如:

JSONPathQueryBuilder.from(jsonData)
    .path("$.store.books..price")
    .limit(10)
    .execute();

9.2 优先使用 Java 便捷方式的场景

如果查询规则:

  • 固定写在 Java 代码中;
  • 需要封装成公共查询方法;
  • 需要和业务逻辑一起维护;
  • 需要显式体现每个路径节点;

可以使用 Java 链式方式。

JSONPathQueryBuilder.from(jsonData)
    .document(JPath.fromRoot(JRoot.ROOT)
        .property("store")
        .property("books")
        .segment(JSegments.recursiveId("price")))
    .limit(10)
    .execute();

两种方式本质上表达的是同一类查询逻辑,选择哪种取决于代码所在的工程场景。

十、四大语法速查表

语法场景 path 写法 Java 便捷方式核心写法
根对象 $.store.books JPath.fromRoot(JRoot.ROOT).property("store").property("books")
访问对象属性 $.store.books .property("store").property("books")
递归下降属性 $.store.books..price .segment(JSegments.recursiveId("price"))
根对象通配符 $.* .property("*")
数组通配符 $.store.books.* .property("store").property("books").property("*")

十一、常见问题

1. 根对象和当前节点有什么区别?

根对象表示从完整 JSON 文档开始查询;当前节点表示从当前上下文开始查询。

固定结构数据通常从根对象开始,嵌套处理和局部查询可以考虑当前节点。

2. 什么时候应该使用递归下降?

当目标字段的层级不固定,或者你只知道字段名、不想手写完整路径时,可以使用递归下降。

3. 通配符会不会返回太多数据?

有可能。通配符会扩大匹配范围,所以建议先用明确路径缩小范围,并结合 limit 控制返回数量。

4. path 和 Java 便捷方式哪个更好?

没有绝对答案:

  • 动态规则、配置化场景适合 path;
  • 固定逻辑、Java 工程封装适合便捷构建方式。

十二、总结

jquick-path 的四大核心语法,可以用一句话概括:

  • 根对象解决“从哪里开始查”;
  • 访问对象属性解决“沿着哪条路径走”;
  • 递归下降解决“层级不确定时怎么找”;
  • 通配符解决“如何批量匹配一组数据”。

这四类语法看起来基础,但它们覆盖了大量真实的 Java JSON 查询场景。

更重要的是,jquick-path 同时提供 path 路径表达式和 Java 便捷访问方式,既适合配置化、规则化使用,也适合在 Java 业务代码中进行封装和复用。

如果你正在寻找:

  • Java JSONPath 查询方案;
  • 轻量级 JSON 数据提取工具;
  • Java JSON 路径表达式库;
  • 支持递归、通配符和属性访问的开源项目;

那么 jquick-path 值得加入你的技术选型清单。

更多完整语法和案例,可以参考项目 [README.md]。

关键词

Java JSONPath、jquick-path、JSONPath 语法、Java JSON 查询、JSON 数据提取、JSONPath 根对象、JSONPath 属性访问、JSONPath 递归下降、JSONPath 通配符、Java 开源项目、CSDN 技术文章

相关文章
|
1天前
|
存储 人工智能 弹性计算
阿里云服务器便宜购买攻略:试用、领券、组合购三步省到底‌,新老用户都省钱‌
本文系统讲解阿里云服务器的实惠采购方法,核心是一套有先后顺序的决策流程:先盘清业务需求与成本构成,再确定计费模式,随后比对活动价、叠加优惠券,最后核算续费口径。新用户可先免费试用,再抢 38 元轻量应用服务器或 99 元、199 元长效特惠款,需多产品协同则优先组合购,选购高性能实例应领券后下单;老用户则可借助大促阶梯满减、AI 用量加速计划等返还机制对冲成本。文中还详细拆解了试用权益差异、五类组合套餐、无门槛券与 AI 体验券的领取条件与操作要点,帮助新老用户按自身阶段理性选型。
|
3天前
|
XML SQL Java
声明式编程——我靠这个“偷懒”方法,写代码效率翻了3倍
本文作者Martin以“躺平式开发”自嘲,实则倡导高效编程——通过声明式编程理念,用配置替代重复代码。他开源jquick工具链(含curl、excel、pdf等),让开发者专注“要什么”,而非“怎么做”,大幅提效降本。
|
2天前
|
XML Java 大数据
声明式Excel样式编排:JQuick-Export STYLE 设计解析与30+配置属性详解
《JQuick-Excel导出STYLE配置手册》详解导出阶段样式配置:支持行/列/单元格三类目标(区域样式暂未生效),涵盖字体、对齐、边框、填充等属性,明确执行时机(写完数据后)、与THEME/FORMULAS/TRANSFORM的协作关系,及SXSSF流式导出限制。含避坑指南与最佳实践。
|
2天前
|
XML Java 测试技术
声明式编程实战:JQuick-Excel 导入三大配置项深度拆解(映射/转换/校验)
本手册详解 JQuick-Excel 导入三大核心配置:MAPPING(字段映射,重命名表头)、TRANSFORM(数据转换,226+内置函数支持字典、日期、字符串等处理)、VALIDATION(原始值校验,含行/列/单元格多级规则)。三者执行顺序固定:校验→映射→转换,语法经源码验证,示例统一采用 XML 声明式写法。(239字)
|
2天前
|
供应链 安全 搜索推荐
旅游服务场景定向钓鱼攻击研究 —— 以新加坡酒店预订诈骗案例为样本
本文以2026年新加坡酒店预订钓鱼诈骗案为样本,剖析依托真实订单数据的定向鱼叉攻击全链路,揭示其利用社会工程、数据泄露与用户心理弱点实施欺诈的机制。研究指出该风险属跨域链式威胁,需旅游平台、通信服务商、金融机构、监管部门及用户协同构建多层防御体系。(239字)
33 3
|
1天前
|
域名解析 存储 人工智能
阿里云企业邮箱网页版入口登录:附企业邮箱费用价格及开通教程
阿里云企业邮箱官网入口:qiye.aliyun.com。注册需先选购版本(标准版600元/年起),再设置管理员密码、分配员工账号、完成域名MX/CNAME解析,全程支持自助开通与钉钉集成。阿里企业邮箱官网:https://t.aliyun.com/U/gNeTEB
55 1
|
3天前
|
Java 测试技术 API
第132篇ContentProvider:跨进程数据共享的标准入口
ContentProvider 是Android四大组件中唯一非UI组件,本质是跨进程的表结构接口+数据变更通知机制。其onCreate早于Application.onCreate,且在所有访问进程里执行,易拖慢冷启动;query走Binder事务,需子线程调用并分页防溢出。核心原则:保持极轻,重初始化移交Application。
28 1
|
开发者 容器
鸿蒙应用开发从入门到实战(十四):ArkUI组件Column&Row&线性布局
ArkUI提供了丰富的系统组件,用于制作鸿蒙原生应用APP的UI,本文主要讲解Column和Row组件的使用以及线性布局的方法。
956 12
|
JavaScript
Vue2按钮组件(Button)
这篇文章介绍了如何在Vue框架中创建一个可自定义样式和行为的按钮组件,包括按钮的文本、类型、尺寸、宽度、高度、圆角、跳转目标、禁用状态和是否居中显示等属性。
742 1
Vue2按钮组件(Button)
|
消息中间件 运维 Prometheus
小红书消息中间件的运维实践与治理之路
近年来,消息领域的全面云原生化逐渐走向深入,比如 RocketMQ 5.0 版本的存算分离设计和 raft 模式,再比如 Kafka3.0 引入了分层设计的方式(tiered storage)和 raft 模式,以及近年来新崛起的 Pulsar 也开始采用云原生架构,在未来都可以针对具体业务需求引入进行功能迭代,发挥组件的最大价值。
1757 128
小红书消息中间件的运维实践与治理之路