跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像AI 生图工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
Javajava

JsonPath 表达式核心用法与实战指南

JsonPath 是用于检索和设置 JSON 数据的表达式语言,支持点符号和括号符号。涵盖操作符、函数、过滤器及常见用法,重点讲解 ReadContext 复用优化、MappingProvider 类型转换、自定义 Predicate 断言以及配置选项如 AS_PATH_LIST 和缓存机制,帮助开发者高效处理 JSON 数据解析任务。

RustyLab发布于 2025/2/4更新于 2026/7/2858 浏览
JsonPath 表达式核心用法与实战指南

概述

JsonPath 类似于 XML 中的 XPath,主要用于路径检索或设置 JSON 数据。它支持两种语法风格:点符号(dot-notation)和括号符号(bracket-notation),例如 $.store.book[0].title 或 $['store']['book'][0]['title']。

基础操作符

符号描述
$查询的根节点对象,表示整个 JSON 数据(数组或对象)
@过滤器断言处理的当前节点对象,类似 Java 中的 this
*通配符,匹配任意名称或数字
..递归搜索(Deep scan),在任何需要名称的地方可用
.表示一个子节点
['' (, '')]表示一个或多个子节点
[ (, )]表示一个或多个数组下标
[start:end]数组片段切片,区间为 [start, end),不包含 end
[?()]过滤器表达式,结果必须为 boolean

内置函数

这些函数可在 JsonPath 表达式执行后调用,输入值为表达式的结果。

名称描述输出类型
min()获取数值类型数组的最小值Double
max()获取数值类型数组的最大值Double
avg()获取数值类型数组的平均值Double
stddev()获取数值类型数组的标准差Double
length()获取数值类型数组的长度Integer

过滤逻辑

过滤器是用于筛选数组的逻辑表达式。典型形式如 [?(@.age > 18)],可以通过逻辑运算符 && 或 || 组合多个条件。字符串需用单引号或双引号包围,例如 [?(@.color == 'blue')]。

操作符描述
==等于(注意数字 1 不等于字符 '1')
!=不等于
< / <=小于 / 小于等于
> / >=大于 / 大于等于
=~正则匹配,例如 [?(@.name =~ /foo.*?/i)]
in包含于,例如 [?(@.size in ['S', 'M'])]
nin排除于
size左右长度匹配
empty判空

实战示例

假设我们有如下 JSON 数据:

{
  "store": {
    "book": [
      { "category": "reference", "author": "Nigel Rees", "title": "Sayings of the Century", "price": 8.95 },
      { "category": "fiction", "author": "Evelyn Waugh", "title": "Sword of Honour", "price": 12.99 },
      { "category": "fiction", "author": "Herman Melville", "title": "Moby Dick", "isbn": "0-553-21311-3", "price": 8.99 },
      { "category": "fiction", "author": "J. R. R. Tolkien", "title": "The Lord of the Rings", "isbn": "0-395-19395-8", "price": 22.99 }
    ],
    "bicycle": { "color": "red", "price": 19.95 }
  },
  "expensive": 10
}
JsonPath 表达式结果说明
$.store.book[*].author 或 $..author所有书籍的作者列表
$.store.*显示 store 下所有叶子节点值
$..price递归查找所有价格字段
$..book[0,1] 或 $..book[:2]前两本书
$..book[-2:]最后两本书
$..book[2:]从索引 2 开始的书
$..book[?(@.isbn)]所有拥有 isbn 属性的书
$.store.book[?(@.price < 10)]价格低于 10 的书
$..book[?(@.price <= $['expensive'])]价格低于 expensive 字段的书
$..book[?(@.author =~ /.*REES/i)]作者名符合正则的书
$..*返回所有节点
$..book.length()书籍数量

常用 API 模式

通常直接使用静态方法 API 进行调用:

String json = "...";
List<String> authors = JsonPath.read(json, "$.store.book[*].author");

这种方式适合单次解析。如果需要对同一个 JSON 解析多次,不建议重复调用 read,因为每次都会重新解析。此时建议使用 ReadContext 或 WriteContext:

String json = "...";
ReadContext ctx = JsonPath.parse(json);
List<String> authorsOfBooksWithISBN = ctx.read("$.store.book[?(@.isbn)].author");

// 使用配置构建器
List<Map<String, Object>> expensiveBooks = JsonPath
    .using(configuration)
    .parse(json)
    .read("$.store.book[?(@.price > 10)]", List.class);

返回值与类型转换

read 后的返回值会自动转型到指定类型。对于明确定义的表达式,应指定对应类型;对于含糊表达式(包含 ..、?[...] 等),通常应使用数组接收。如需转换成具体类型,可通过 configuration 配置 mappingProvider:

String json = "{\"date_as_long\" : 1411455611975}";
Date date = JsonPath.parse(json).read("$['date_as_long']", Date.class); // 使用 JsonSmartMappingProvider
Book book = JsonPath.parse(json).read("$.store.book[0]", Book.class); // 使用 GsonMappingProvider

自定义映射提供者

JsonPath 支持 SPI 扩展反序列化器。默认使用 JsonSmartMappingProvider,它注册了基本数据类型的转换逻辑。若需切换 Provider(例如使用 Jackson),可配置如下:

Configuration.setDefaults(new Configuration.Defaults() {
    private final JsonProvider jsonProvider = new JacksonJsonProvider();
    private final MappingProvider mappingProvider = new JacksonMappingProvider();

    @Override public JsonProvider jsonProvider() { return jsonProvider; }
    @Override public MappingProvider mappingProvider() { return mappingProvider; }
    @Override public Set<Option> options() { return EnumSet.noneOf(Option.class); }
});

断言谓词实现

创建过滤器断言有三种方式:

1. Inline Predicates

直接在表达式中使用 ?[<@expression>]:

List<Map<String, Object>> books = JsonPath.parse(json)
    .read("$.store.book[?(@.price < 10)]");

2. Filter API

使用 Filter 类构建复杂逻辑:

import static com.jayway.jsonpath.JsonPath.parse;
import static com.jayway.jsonpath.Criteria.where;
import static com.jayway.jsonpath.Filter.filter;

Filter cheapFictionFilter = filter(
    where("category").is("fiction").and("price").lte(10D)
);
List<Map<String, Object>> books = parse(json).read("$.store.book[?]", cheapFictionFilter);

// 支持 or 和 and 组合
Filter fooOrBar = filter(where("foo").exists(true)).or(where("bar").exists(true));

注意:表达式中必须有占位符 ?,多个占位符会按顺序替换。

3. 自定义 Predicate

实现 Predicate 接口处理特殊逻辑:

Predicate booksWithISBN = new Predicate() {
    @Override
    public boolean apply(PredicateContext ctx) {
        return ctx.item(Map.class).containsKey("isbn");
    }
};
List<Map<String, Object>> books = reader.read("$.store.book[?].isbn", List.class, booksWithISBN);

获取路径列表

有时需要获取匹配到的完整路径而非值,可使用 AS_PATH_LIST 选项:

Configuration conf = Configuration.builder()
    .options(Option.AS_PATH_LIST)
    .build();
List<String> pathList = using(conf).parse(json).read("$..author");
// 结果示例:
// "$['store']['book'][0]['author']"
// "$['store']['book'][1]['author']"

配置选项详解

DEFAULT_PATH_LEAF_TO_NULL

检索不到时返回 null 而不是抛出异常。默认行为是抛出 PathNotFoundException。

Configuration conf2 = conf.addOptions(Option.DEFAULT_PATH_LEAF_TO_NULL);
String gender1 = JsonPath.using(conf2).parse(json).read("$[1]['gender']"); // 返回 null

ALWAYS_RETURN_LIST

总是返回 List,即使结果是单个非 List 类型也会被包装。

SUPPRESS_EXCEPTIONS

不抛出异常。开启 ALWAYS_RETURN_LIST 时返回空 List,否则返回 null。

AS_PATH_LIST

返回路径列表(见上文)。

REQUIRE_PROPERTIES

禁止使用通配符,否则抛出异常。

缓存机制

每次 read 都会尝试获取缓存以提高性能,但默认未启用。JsonPath 2.1.0+ 提供了新的 SPI 缓存实现:

  • NOOPCache: 无缓存
  • LRUCache: 默认实现,线程安全

如需自定义缓存:

CacheProvider.setCache(new Cache() {
    private Map<String, JsonPath> map = new HashMap<>();
    @Override public JsonPath get(String key) { return map.get(key); }
    @Override public void put(String key, JsonPath jsonPath) { map.put(key, jsonPath); }
});

目录

  1. 概述
  2. 基础操作符
  3. 内置函数
  4. 过滤逻辑
  5. 实战示例
  6. 常用 API 模式
  7. 返回值与类型转换
  8. 自定义映射提供者
  9. 断言谓词实现
  10. 1. Inline Predicates
  11. 2. Filter API
  12. 3. 自定义 Predicate
  13. 获取路径列表
  14. 配置选项详解
  15. DEFAULTPATHLEAFTONULL
  16. ALWAYSRETURNLIST
  17. SUPPRESS_EXCEPTIONS
  18. ASPATHLIST
  19. REQUIRE_PROPERTIES
  20. 缓存机制
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • GitHub Copilot 学生认证流程与 Python 自动化实现
  • 2026 年 3 月大模型全景解析:国产登顶与 Agent 工业化落地
  • FPGA 模块助力现代工厂实现高速数据采集和实时处理
  • 在 PyCharm 中配置和使用 Git 工具
  • PaddlePaddle 镜像运行 Stable Diffusion 的可行性分析
  • 使用 KSWEB 在安卓部署 Typecho 博客并实现外网访问
  • GitHub 个人访问令牌 PAT 生成及 R 环境凭证管理与包安装配置
  • ComfyUI v0.18.0 发布:显存内存优化、VAE 架构进化与 API 前端升级
  • OpenClaw 开源 AI 智能体项目精选与部署指南
  • Qwen3-VL 法律场景长文档 OCR 结构化解析教程
  • SystemVerilog 教程:从基础到高级验证
  • PDF Arranger终极指南:快速掌握PDF页面重排的完整教程
  • 本地部署 Stable Diffusion 3.5 完整教程
  • Vivado 安装指南:从官网下载到环境配置
  • llama.cpp 多 GPU 分布式计算优化实践指南
  • VS2022 中 EPPlus 库安装、许可设置及使用指南
  • 即梦 AI 基础操作指南:绘画与视频生成入门
  • Qwen3-ASR-1.7B 实战案例:新闻发布会实时语音转写与关键人物发言提取
  • ClawPanel:OpenClaw 智能管理面板及 Docker 部署指南
  • 基于 Neo4j 知识图谱的智能问答系统设计

相关免费在线工具

  • Keycode 信息

    查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

  • Escape 与 Native 编解码

    JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

  • JavaScript / HTML 格式化

    使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online

  • JavaScript 压缩与混淆

    Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online