• JsonPath:针对json的强大的规则解析与参数查找工具


    项目特点

    GitHub项目地址:https://github.com/json-path/JsonPath
    主要功能:

    1. 将Json字符串转为Java Map对象(这个不算什么,FastJson之类的工具都可以)
    2. 通过强大的规则表达式定位字段,返回字段值或值集合(很厉害)

    支持的规则表达式以及示例(选自项目readme):

    JsonPath (点击测试) 结果
    $.store.book[*].author The authors of all books
    $..author All authors
    $.store.* All things, both books and bicycles
    $.store..price The price of everything
    $..book[2] The third book
    $..book[-2] The second to last book
    $..book[0,1] The first two books
    $..book[:2] All books from index 0 (inclusive) until index 2 (exclusive)
    $..book[1:2] All books from index 1 (inclusive) until index 2 (exclusive)
    $..book[-2:] Last two books
    $..book[2:] Book number two from tail
    $..book[?(@.isbn)] All books with an ISBN number
    $.store.book[?(@.price < 10)] All books in store cheaper than 10
    ..book[?(@.price<=['expensive'])] All books in store that are not "expensive"
    $..book[?(@.author =~ /.*REES/i)] All books matching regex (ignore case)
    $..* Give me every thing
    $..book.length() The number of books

    实战测试

    就用项目readme文档提供的例子进行测试:

    json格式字符串,点击查看
    {
        "store": {
            "book": [
                {
                    "category": "reference",
                    "author": "Nigel Rees",
                    "title": "Sayings of the Century",
                    "price": 8.95
                },
                {
                    "category": "fiction",
                    "author": "Evelyn Waugh",
                    "title": "Sword of Honour",
                    "price": 12.99
                },
                {
                    "category": "fiction",
                    "author": "Herman Melville",
                    "title": "Moby Dick",
                    "isbn": "0-553-21311-3",
                    "price": 8.99
                },
                {
                    "category": "fiction",
                    "author": "J. R. R. Tolkien",
                    "title": "The Lord of the Rings",
                    "isbn": "0-395-19395-8",
                    "price": 22.99
                }
            ],
            "bicycle": {
                "color": "red",
                "price": 19.95
            }
        },
        "expensive": 10
    }
    

    POM中引入依赖:

    <dependency>
        <groupId>com.jayway.jsonpath</groupId>
        <artifactId>json-path</artifactId>
        <version>2.7.0</version>
    </dependency>
    

    写一个单元测试类:

    @SpringBootTest
    @RunWith(MockitoJUnitRunner.class)
    public class JsonPathTest {
        private final String jsonStr = "...";
        private final Object context = Configuration.defaultConfiguration().jsonProvider().parse(jsonStr);
    
        @Test
        public void test(){}
    }
    

    其中:

    1. 第二个注解可以做到启动SpringBoot测试类而无需启动SpringApplication,并且也可以做到组件注入等功能。
    2. jsonStr用来指代之前所述的json字符串,这里简略写。
    3. context实际上是由json字符串通过默认配置生成的一个Map<String, Object>。

    先看看context的类型:

    System.out.println("context的类型:" + context.getClass().getSimpleName() + "\n");
    ------------------------------------------------------------------
    output: context的类型:LinkedHashMap
    

    用法1:通过key定位一个value:

    jsonpath = "$.store.book[1].price";
    result = JsonPath.read(testMap, jsonpath);
    System.out.println("contents on " + jsonpath + ": " + result + "\n");
    ------------------------------------------------------------------
    output: contents on $.store.book[1].price: 12.99
    

    用法2:通过key定位一组value:

    jsonpath = "$.store.book[*].price";
    result = JsonPath.read(context, jsonpath);
    System.out.println("contents on " + jsonpath + ": " + result + "\n");
    ------------------------------------------------------------------
    output: contents on $.store.book[*].price: [8.95,12.99,8.99,22.99]
    

    这里如果去查看result的type,会发现它是JSONArray类型,是List<Object>接口的实现,当List用就可以了。

    用法3:向下递归查找:

    jsonpath = "$..price";
    result = JsonPath.read(context, jsonpath);
    System.out.println("contents on " + jsonpath + ": " + result);
    ------------------------------------------------------------------
    output: contents on $..price: [8.95,12.99,8.99,22.99,19.95]
    

    在测试的时候想起一个问题,设想这样的场景,如果我们已经有了这样一个Map,只需要JsonPath提供的规则表达式解析与查找能力,那么想要使用JsonPath是不是需要Map->JsonString->context->规则解析->查找结果?答案是不需要的。
    我们已经知道这个context本就是一个Map类型,那么是不是可以省去中间转为json string的步骤呢?我们测试看看:

    //1. 先将json解析为一个Map
    Map<String, Object> testMap = (Map) JSONObject.parseObject(JSON_STRING);
    jsonpath = "$..price";
    //2. 再将Map传入read方法,看是否能查找到结果:
    result = JsonPath.read(testMap, jsonpath);
    System.out.println("contents on " + jsonpath + ": " + result);
    ------------------------------------------------------------------
    output: contents on $..price: [8.95,12.99,8.99,22.99,19.95]
    

    可以看出,JsonPath的搜索规则解析能力是支持对普通Map进行查找的。

  • 相关阅读:
    2000-2021年全国各省资本存量测算数据(含原始数据+测算过程+计算结果)
    VitualBox安装增强功能实现无缝模式和拖放功能(踩坑点记录汇总)
    Azure 机器学习 - 如何使用模板创建安全工作区
    算法刷题-哈希表-有效的字母异位词
    移动通信网络规划:频谱划分
    Docker镜像原理
    深度解读财团参与Twitter私有化的投资逻辑
    经典卷积神经网络模型 - InceptionNet
    PerformanceRunner国产化性能测试工具
    json数据格式的理解(前+后)
  • 原文地址:https://www.cnblogs.com/gigabit/p/16477715.html