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 转载请注明来源

相关推荐
鲤籽鲲1 分钟前
C# Random 随机数 全面解析
android·java·c#
zquwei20 分钟前
SpringCloudGateway+Nacos注册与转发Netty+WebSocket
java·网络·分布式·后端·websocket·网络协议·spring
TT哇27 分钟前
*【每日一题 提高题】[蓝桥杯 2022 国 A] 选素数
java·算法·蓝桥杯
dessler42 分钟前
Docker-run命令详细讲解
linux·运维·后端·docker
火烧屁屁啦1 小时前
【JavaEE进阶】初始Spring Web MVC
java·spring·java-ee
w_31234541 小时前
自定义一个maven骨架 | 最佳实践
java·maven·intellij-idea
岁岁岁平安1 小时前
spring学习(spring-DI(字符串或对象引用注入、集合注入)(XML配置))
java·学习·spring·依赖注入·集合注入·基本数据类型注入·引用数据类型注入
武昌库里写JAVA1 小时前
Java成长之路(一)--SpringBoot基础学习--SpringBoot代码测试
java·开发语言·spring boot·学习·课程设计
Q_19284999061 小时前
基于Spring Boot的九州美食城商户一体化系统
java·spring boot·后端