Jayway JsonPath-提取JSON文档内容的Java DSL | 京东物流技术团队
介绍
JsonPath是一种能够提取部分JSON文档属性、对象、数组的语法,支持条件过滤、数学运算、字符串处理等功能。JsonPath与JSON文档就像 XPath 表达式与 XML 文档结合使用一样。
由于 JSON 结构通常是匿名的,并不一定和XML一样具有“根成员对象”,因此 JsonPath假定分配$给外层对象的抽象名称。JsonPath由用点分隔的表达式段(操作符)组成。 操作符可以是一个简单的词,如 JSON 值名称、*,也可以是括在方括号 [ ] 中的更复杂的构造。 括号段前的分隔点是可选的,也可以省略。下面是几种JsonPath的提取JSON文档内容语法:
JsonPath | 描述 |
---|---|
$.object.name | 返回object.name的内容。 |
$.object['name'] | 返回object.name的内容。 |
$.object.['name'] | 返回object.name的内容。 |
$.object.history.length() | 返回object.history数组元素的个数。 |
$[?(@.name == 'Object')].price.first() | 返回第一个名为'Object'的对象的价格字段。 |
$[?(@.price > 10)].length() | 返回price大于10的对象个数。 |
Jayway JsonPath 是 Stefan Goessner JsonPath的Java实现,是用于读取JSON文档的Java DSL。本文主要通过Jayway JsonPath来简单介绍JsonPath的使用语法,通过真实报文案例来进行操作。
支持的操作符
操作符 | 描述 |
---|---|
$ | 查询的根节点对象,表示一个json的数据,可以是对象或数组 |
@ | 当前节点对象 |
* | 通配符,获取所有节点 |
.. | 递归查找,查找所有层次的属性值 |
<name> | 按名称匹配对象属性。 |
.<name> | 按照名称查找子节点 |
['<name>','<name>',...] | 可用查找多个节点 |
[<number>,<number>,...] | 按索引匹配数组元素,可同时查找多个数组元素 |
[start:end] | 按定义的范围匹配数组元素:<start> - 要匹配的第一个索引(包括)。 如果未指定,则匹配从头开始的所有数组元素。 如果为负数,则指定从数组末尾开始的偏移量。<end> - 要匹配的最后一个索引(不包括)。 如果未指定,则匹配所有数组元素到最后。 如果为负数,则指定从数组末尾开始的偏移量。 |
[?(<expression>)] | 过滤表达式可匹配对象/数组元素,表达式的结果必须为布尔值 |
可以通过在 JSONPath 中添加 ~ 后缀来提取匹配的元素名称。 它返回匹配对象的名称或匹配数组项的字符串格式的索引。
过滤操作符
操作符 | 描述 |
---|---|
== | 等于 |
!= | 不等于 |
< | 小于 |
<= | 小于或等于 |
> | 大于 |
>= | 大于或等于 |
=~ | 匹配正则表达式 [?(@.name =~ /foo.*?/i)] |
in | 包含 [?(@.size in ['S', 'M'])] |
nin | 不包含 |
subsetof | 子集 [?(@.sizes subsetof ['S', 'M', 'L'])] |
anyof | 交集 [?(@.sizes anyof ['M', 'L'])] |
noneof | 不是交集 [?(@.sizes noneof ['M', 'L'])] |
size | 左侧(数组或字符串)的大小应与右侧匹配 |
empty | 左侧(数组或字符串)应该为空 |
支持的函数
可以在JsonPath表达式执行后进行调用,其输入值为表达式的结果。函数的输出看具体某个函数的含义。
函数 | 描述 | 返回值类型 |
---|---|---|
min() | 数值类型数组最小值 | Double |
max() | 数值类型数组最大值 | Double |
avg() | 数值类型数组平均值 | Double |
stddev() | 数值类型数组标准差 | Double |
length() | 数组长度 | Integer |
sum() | 数值类型数组求和 | Double |
keys() | 提取匹配的元素名称与~ 操作符功能一致 | Set<E> |
concat(X) | 拼接 | 与入参相同 |
append(X) | 把元素添加到JsonPath输出的数组中 | 与入参相同 |
first() | 数组中的第一个元素 | 数组中元素类型 |
last() | 数组中的最后一个元素 | 数组中元素类型 |
index(X) | 提供索引为X的数组的元素,如果X为负数,则从后往前取 | 数组中元素类型 |
用一个复杂的接单报文来演示
https://jsonpath.com,这个在线网站可以用来验证JsonPath表达式,但是不支持函数,函数可以通过java
代码来验证。
String json ="{.....}"; Object read = JsonPath.read(json, "$..price.min()"); System.out.println(read);
示例报文
{ "address":"大良街道同兴路****", "createTime":"2023-09-20 17:48:44", "customerName":"培^_^", "id":0, "memberId":"ECP002000*****", "mobile":"184^_^8547", "extendMessage":{ "clientNo":"testEBU516154", "clientName":"广州网络科技有限公司", "spSoNo":"test1976065878296", "road":"011" }, "odOrderDetailList":[ { "id":1, "productName":"白医生中频针灸理疗仪家用医院医用多功能颈椎肩周炎腰肌劳损电疗经络激光低频按摩器同款中频激光综合治疗仪 2023新款", "quantity":1, "productSku":"38fjjjj", "price":189.6 }, { "id":2, "productName":"测试SKU", "quantity":3, "productSku":"ESG03JJ1", "price":200 } ], "totalPrice":0, "volume":17318.4, "extendInfo":{ "templateInfo":[ { "code":"TP123", "isPrint":1, "type":2, "printType":0 }, { "code":"TPABC", "isPrint":1, "type":4, "printType":0 } ], "attrs":{ "plateFormCode":"274" }, "senderName":"流苏", "senderAddress":"广东省中山市南头镇永辉北路*****", "paymentTime":"2023-09-20 17:22:31" }, "carrierName":"京东配送", "provinceName":"广东", "isConsumable":0, "merchantType":"0", "tags":[ "a", "b", "c", "d", "e" ] }
操作结果
JsonPath | 结果 |
---|---|
$.extendMessage.clientName | "广州网络科技有限公司" |
$.extendMessage['clientNo'] | "testEBU516154" |
$.extendMessage | {"clientNo":"testEBU516154","clientName":"广州网络科技有限公司","spSoNo":"test1976065878296","road":"011"} |
$.odOrderDetailList[0].productName | "白医生中频针灸理疗仪家用医院医用多功能颈椎肩周炎腰肌劳损电疗经络激光低频按摩器同款中频激光综合治疗仪 2023新款" |
$.odOrderDetailList[-1].productName | "测试SKU" |
$.odOrderDetailList.length() | 2 |
$.tags[:] | ["a", "b", "c", "d", "e" ] |
$.tags[2:] | ["c", "d", "e" ] |
$.tags[:3] | ["a", "b", "c"] |
$.tags[1:4] | ["b", "c", "d"] |
$.tags[-2:] | ["d", "e"] |
$.tags[:-3] | ["a", "b"] |
$.tags[:-3].length() | 2 |
$.odOrderDetailList[0,1].productName | "白医生中频针灸理疗仪家用医院医用多功能颈椎肩周炎腰肌劳损电疗经络激光低频按摩器同款中频激光综合治疗仪 2023新款", "测试SKU" |
$.odOrderDetailList[1].[productName,price] | "测试SKU", 200 |
$..id | 0,1,2 |
$.odOrderDetailList[?(@.id == 4 - 0.4 * 5)].productSku | "ESG03JJ1" |
$.odOrderDetailList[?(@.id == 1 || @.id == 2)].productSku | "38fjjjj", "ESG03JJ1" |
$.extendInfo.templateInfo[?(!(@.type == 2))].code | "TPABC" |
$.extendInfo.templateInfo[?((@.type != 2))].code | "TPABC" |
$.odOrderDetailList[?(@.price > 190)].productName | "测试SKU" |
$.odOrderDetailList[?(@.id> $.id)].productSku | ["38fjjjj","ESG03JJ1"] |
$..[?(@.productSku)] | [{"id":1,"productName":"白医生中频针灸理疗仪家用医院医用多功能颈椎肩周炎腰肌劳损电疗经络激光低频按摩器同款中频激光综合治疗仪 2023新款","quantity":1,"productSku":"38fjjjj","price":189.6},{"id":2,"productName":"测试SKU","quantity":3,"productSku":"ESG03JJ1","price":200}] |
$..tags.length() | 5 |
$.odOrderDetailList[*].price.min() | 189.6 |
$..price.max() | 200 |
作者:京东物流 马红岩
来源:京东云开发者社区 自猿其说 Tech 转载请注明来源

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
GPTs 初体验 - 1 分钟就能创建一个自己的 ChatGPT? | 京东云技术团队
就在 11.10 号早上,ChatGPT 已经偷摸的把GPTs功能,开放给所有尊贵的 Plus 用户了。 随着这波的功能开放,界面也是改了不少。点击左侧的 Explore 或者左下角的用户处,就可以直接进入新的 GPTs 功能: 这里可以看到我们自己创建的 GPT,下面呢还有 OpenAI 官方出品的 GPTs : 不过这些官方的,目前看起来更像是一个个的提示词包,貌似没啥惊艳的,毕竟现在谁还没个提示词市场呢 点击 Create a GPT 之后,会进入 GPTs 的创建页面,左侧是 GPT Builder,右边是实时的预览: 左边这个 Builder 很有意思,可以以交互的形式,实时创建我们自己的 GPT。 就像 C 语言的编译器 gcc 是 C 语言写的一样, 现在可以拿 ChatGPT 给我们创建 ChatGPT 了,还是交互式的创建,非常爽! 这里做一个知识库问答的 GPT,以 awesome-java 这个38K star 的仓库作为基础数据: 几秒钟之后,GPT 已经帮我做好了 GPT,在右边就可以直接预览,甚至贴心的给我这个 GPT 起了个名字:Java Resource...
- 下一篇
时间复杂度为 O(nlogn) 的排序算法 | 京东物流技术团队
归并排序 归并排序遵循分治的思想:将原问题分解为几个规模较小但类似于原问题的子问题,递归地求解这些子问题,然后合并这些子问题的解来建立原问题的解,归并排序的步骤如下: 划分:分解待排序的 n 个元素的序列成各具 n/2 个元素的两个子序列,将长数组的排序问题转换为短数组的排序问题,当待排序的序列长度为 1 时,递归划分结束 合并:合并两个已排序的子序列得出已排序的最终结果 归并排序的代码实现如下: private void sort(int[] nums, int left, int right) { if (left >= right) { return; } // 划分 int mid = left + right >> 1; sort(nums, left, mid); sort(nums, mid + 1, right); // 合并 merge(nums, left, mid, right); } private void merge(int[] nums, int left, int mid, int right) { //...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Docker安装Oracle12C,快速搭建Oracle学习环境
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库
- CentOS7设置SWAP分区,小内存服务器的救世主
- SpringBoot2整合Redis,开启缓存,提高访问速度
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- CentOS7,CentOS8安装Elasticsearch6.8.6
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- 2048小游戏-低调大师作品