栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

继 Gson、Jackson、FastJson 之后基于JsonPath解析JSON

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

继 Gson、Jackson、FastJson 之后基于JsonPath解析JSON

基于JsonPath解析JSON
    • 一、JsonPath 说明
    • 二、JsonPath 语法
      • 1. 常用操作符
      • 2. 常用过滤器操作符
      • 3. 常用函数
    • 三、Java 语言实现JsonPath示例
      • 1. 引入 maven 坐标
      • 2. 数据准备
      • 3. json解析示例
    • 四、JsonPath 其他功能

一、JsonPath 说明

JsonPath是一种用于读取JSON文档的JavaDSL,能够方便快捷的解析复杂逻辑的Json。GitHub:JsonPath ,当然也可以 在线使用。

二、JsonPath 语法 1. 常用操作符
OperatorDescription
$要查询的根元素。表示所有表达式的开始路径
@用在筛选器,表示当前节点
*作为通配符,匹配所有成员
..子递归通配符,匹配成员的所有子元素
..孩子节点名称
['' (, '')]括号中标注的一个或多个孩子节点
[ (, )]括号中标注一个或多个孩子节点的下标(索引),从0开始
[start:end]表示从start下标开始到 end下标结束(不包括 end 下标)孩子节点
[?()]过滤表达式。表达式的计算结果必须为布尔值
2. 常用过滤器操作符
OperatorDescription
==左侧等于右侧。但是 1 不等于 ‘1’
!=左侧不等于右侧
<左侧小于右侧
<=左侧小于等于右侧
>左侧大于右侧
>=左侧大于等于右侧
=~左侧正则匹配右侧
in左侧存在于右侧集合
nin左侧不存在于右侧集合
size左侧(数组或字符串)的大小应与右侧匹配
empty左侧(数组或字符串)应为空
subsetof左侧是右侧的子集。测试时发现无法调通
anyof左侧与右侧的交集。测试时发现无法调通
noneof左侧和右侧不相交的部分。测试时发现无法调通
3. 常用函数
FunctionDescriptionOutput type
min()返回数组的最小值Double
max()返回数组的最大值Double
avg()返回数组的平均值Double
stddev()返回数组的标准方差Double
length()返回数组的长度Integer
sum()返回数组的总和Double
keys()没搞明白这个函数是做什么的Set
concat(X)将数组中元素拼接成一个新的元素like input
append(X)在 json 上添加元素。测试发现没有作用,提示没有该函数like input
三、Java 语言实现JsonPath示例 1. 引入 maven 坐标

    com.jayway.jsonpath
    json-path
    2.7.0

2. 数据准备

添加json文件 /json/ExampleJson.json ,内容如下所示:

{
  "store": [
    {
      "name": "京东",
      "label": "like",
      "book": [
        {
          "category": "Java",
          "author": "凯·S·霍斯特曼",
          "title": "Java核心技术",
          "price": 149,
          "nation": "M"
        },
        {
          "category": "Java",
          "author": "Bruce Eckel",
          "title": "Java编程思想",
          "price": 54.13,
          "nation": "M"
        },
        {
          "category": "Java",
          "author": "方腾飞",
          "title": "Java并发编程的艺术",
          "price": 48.12,
          "nation": "C"
        },
        {
          "category": "C++",
          "author": "安东尼威廉姆斯",
          "title": "C++并发编程实战",
          "price": 137.00,
          "nation": "M"
        },
        {
          "category": "",
          "author": "未知",
          "title": "测试",
          "price": 0,
          "nation": "C"
        }
      ],
      "bicycle": {
        "color": "red",
        "price": 1999.99
      },
      "avg": 60
    },
    {
      "name": "天猫",
      "book": [
        {
          "category": "Python",
          "author": "埃里克·马瑟斯 ",
          "title": "Python从入门到实践",
          "price": 107,
          "nation": "M"
        },
        {
          "category": "Python",
          "author": "明日科技",
          "title": "Python从入门到精通",
          "price": 36.80,
          "nation": "C"
        }
      ]
    }
  ],
  "from": "互联网"
}
3. json解析示例
package com.study;


import com.jayway.jsonpath.JsonPath;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.InputStream;


class JsonPathExampleTest {

    private InputStream resource;
    private static final Logger LOGGER = LoggerFactory.getLogger(JsonPathExampleTest.class);

    @BeforeEach
    void setUp() {
        resource = JsonPathExample.class.getResourceAsStream("/json/ExampleJson.json");
    }

    @Test
    void getAllBookListList() throws IOException {
        Object books = JsonPath.read(resource, "$..book");
        LOGGER.info("获取全部 book 节点:{}", books);
        Assertions.assertNotNull(books);
    }

    @Test
    void getAllBookList() throws IOException {
        Object books = JsonPath.read(resource, "$..book[*]");
        LOGGER.info("获取全部 book 节点:{}", books);
        Assertions.assertNotNull(books);
    }

    @Test
    void getAllAuthors() throws IOException {
        Object authors = JsonPath.read(resource, "$..author");
        LOGGER.info("获取全部 book 的 author:{}", authors);
        Assertions.assertNotNull(authors);
    }

    @Test
    void getJingdong() throws IOException {
        Object o = JsonPath.read(resource, "$.store[0]");
        LOGGER.info("获取京东store:{}", o);
        Assertions.assertNotNull(o);
    }

    @Test
    void getBicycleFromJingdong() throws IOException {
        Object o = JsonPath.read(resource, "$.store[0].bicycle");
        LOGGER.info("获取京东 store 下的 bicycle:{}", o);
        Assertions.assertNotNull(o);
    }

    @Test
    void getFirstBookFromJingdong() throws IOException {
        Object o = JsonPath.read(resource, "$.store[0].book[0]");
        LOGGER.info("获取京东 store 下的第一的 book:{}", o);
        Assertions.assertNotNull(o);
    }

    @Test
    void getLastBookFromJingdong() throws IOException {
        Object o = JsonPath.read(resource, "$.store[0].book[-1]");
        LOGGER.info("获取京东 store 下的最后的 book:{}", o);
        Assertions.assertNotNull(o);
    }

    @Test
    void getFirstBookOfAuthorFromJingdong() throws IOException {
        Object o = JsonPath.read(resource, "$.store[0].book[0]['author', 'title']");
        LOGGER.info("获取京东 store 下的第一的 book 的 author 和 title:{}", o);
        Assertions.assertNotNull(o);
    }

    @Test
    void getFirstAndThirdBookOfAuthorFromJingdong() throws IOException {
        Object o = JsonPath.read(resource, "$.store[0].book[0, 2]");
        LOGGER.info("获取京东 store 下的第一和第三的 book:{}", o);
        Assertions.assertNotNull(o);
    }

    @Test
    void getFirstToThirdBookOfAuthorFromJingdong() throws IOException {
        Object o = JsonPath.read(resource, "$.store[0].book[0:3]");
        LOGGER.info("获取京东 store 下的第一到第三的 book:{}", o);
        Assertions.assertNotNull(o);
    }

    @Test
    void getExistLabel() throws IOException {
        Object o = JsonPath.read(resource, "$.store[?(@.label)]");
        LOGGER.info("获取 store 下存在 label 的 store:{}", o);
        Assertions.assertNotNull(o);
    }

    @Test
    void getNameEqual() throws IOException {
        Object o = JsonPath.read(resource, "$.store[?(@.name=='京东')]");
        LOGGER.info("获取 name=京东 的 store:{}", o);
        Assertions.assertNotNull(o);
    }

    @Test
    void getPriceGT100() throws IOException {
        Object o = JsonPath.read(resource, "$..book[?(@.price > 100)]");
        LOGGER.info("获取 price 大于 100 的 book:{}", o);
        Assertions.assertNotNull(o);
    }

    @Test
    void getPriceGTAvg() throws IOException {
        Object o = JsonPath.read(resource, "$..book[?(@.price > $.store[0].avg)]");
        LOGGER.info("获取 price 大于 avg 的 book:{}", o);
        Assertions.assertNotNull(o);
    }

    @Test
    void getCategoryEmpty() throws IOException {
        Object o = JsonPath.read(resource, "$..book[?(@.category == '')]");
        LOGGER.info("获取 Java 和 Python 的 book:{}", o);
        Assertions.assertNotNull(o);
    }

    @Test
    void getJavaAndPython() throws IOException {
        Object o = JsonPath.read(resource, "$..book[?(@.category in ['Java', 'Python'])]");
        LOGGER.info("获取 Java 和 Python 的 book:{}", o);
        Assertions.assertNotNull(o);
    }
    
    @Test
    void getMaxPrice() throws IOException {
        Object o = JsonPath.read(resource, "max($..book[?(@.price)].price)");
        LOGGER.info("获取 book 中最高的 price:{}", o);
        Assertions.assertNotNull(o);
    }
    
    @Test
    void getConcatPrice1() throws IOException {
        Object o = JsonPath.read(resource, "concat($..book[?(@.price)].price)");
        LOGGER.info("获取 book 中的price并拼接起来:{}", o);
        Assertions.assertEquals(o, "14954.1348.12137.0010736.8");
    }

    @Test
    void getConcatPrice2() throws IOException {
        Object o = JsonPath.read(resource, "$..book[?(@.price)].price.concat()");
        LOGGER.info("获取 book 中的price并拼接起来:{}", o);
        Assertions.assertEquals(o, "14954.1348.12137.0010736.8");
    }
}
四、JsonPath 其他功能
  1. 设置指定路径的json值

    @Test
    void setValue() {
        String newJson = JsonPath.parse(resource).set("$.from", "oy").jsonString();
        LOGGER.info("设置后的新json:{}", newJson);
        Assertions.assertNotNull(newJson);
    }
    

    注意: 设置值的 path 必须存在,否则报 PathNotFoundException 异常。

  2. 支持缓存,支持自定义
    com.jayway.jsonpath.spi.cache.LRUCache (default, thread safe)
    com.jayway.jsonpath.spi.cache.NOOPCache (no cache)
    自定义缓存使用 CacheProvider.setCache()

  3. JsonProvider SPI
    JsonSmartJsonProvider (default)
    JacksonJsonProvider
    JacksonJsonNodeJsonProvider
    GsonJsonProvider
    JsonOrgJsonProvider
    JakartaJsonProvider

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/825864.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号