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 JsonPathStefan 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为负数,则从后往前取 数组中元素类型

用一个复杂的接单报文来演示

jsonpath.com,这个在线网站可以用来验证JsonPath表达式,但是不支持函数,函数可以通过java代码来验证。

ini 复制代码
String json ="{.....}";
Object read = JsonPath.read(json, "$..price.min()");
System.out.println(read);

示例报文

css 复制代码
{
    "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" |
| <math xmlns="http://www.w3.org/1998/Math/MathML"> . o d O r d e r D e t a i l L i s t [ ? ( @ . i d > .odOrderDetailList[?(@.id> </math>.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 转载请注明来源

相关推荐
卓越小Y13 分钟前
配置jellyfin docker 硬件加速
java·spring cloud·docker
白萝卜弟弟15 分钟前
【JAVA】正则表达式中的捕获组和非捕获组
java·正则表达式
袁庭新36 分钟前
LuaRocks如何安装数据库驱动?
java·数据库·redis·lua·luarocks·袁庭新
hummhumm44 分钟前
第 10 章 - Go语言字符串操作
java·后端·python·sql·算法·golang·database
nukix1 小时前
Mac Java 使用 tesseract 进行 ORC 识别
java·开发语言·macos·orc
月光光心慌慌。1 小时前
新日撸java三百行` 新手小白java学习记录 `Day1
java
蘑菇丁1 小时前
ranger-kms安装
java·ide·eclipse
XiaoLeisj1 小时前
【JavaEE初阶 — 多线程】内存可见性问题 & volatile
java·开发语言·java-ee
weixin_462428471 小时前
使用 Caffeine 缓存并在业务方法上通过注解实现每3到5秒更新缓存
java·缓存
程序媛小果1 小时前
基于java+SpringBoot+Vue的桂林旅游景点导游平台设计与实现
java·vue.js·spring boot