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

相关推荐
罗政2 小时前
[附源码]超简洁个人博客网站搭建+SpringBoot+Vue前后端分离
vue.js·spring boot·后端
架构文摘JGWZ3 小时前
Java 23 的12 个新特性!!
java·开发语言·学习
拾光师4 小时前
spring获取当前request
java·后端·spring
aPurpleBerry4 小时前
neo4j安装启动教程+对应的jdk配置
java·neo4j
我是苏苏4 小时前
Web开发:ABP框架2——入门级别的增删改查Demo
java·开发语言
xujinwei_gingko4 小时前
Spring IOC容器Bean对象管理-Java Config方式
java·spring
2301_789985944 小时前
Java语言程序设计基础篇_编程练习题*18.29(某个目录下的文件数目)
java·开发语言·学习
IT学长编程4 小时前
计算机毕业设计 教师科研信息管理系统的设计与实现 Java实战项目 附源码+文档+视频讲解
java·毕业设计·springboot·毕业论文·计算机毕业设计选题·计算机毕业设计开题报告·教师科研管理系统
m0_571957584 小时前
Java | Leetcode Java题解之第406题根据身高重建队列
java·leetcode·题解
程序猿小D4 小时前
第二百三十五节 JPA教程 - JPA Lob列示例
java·数据库·windows·oracle·jdk·jpa