zoukankan      html  css  js  c++  java
  • Java使用JSONPath解析JSON完整内容详解

    简介

      JsonPath是一种简单的方法来提取JSON文档的方法。它支持的编程语言有很多,如java、python、JavaScript和PHP。

      JsonPath提供的json解析非常强大,它提供了类似正则表达式的语法,基本上可以满足所有你想要获得的json内容。

    maven依赖

    <!-- https://mvnrepository.com/artifact/com.jayway.jsonpath/json-path -->
    <dependency>
        <groupId>com.jayway.jsonpath</groupId>
        <artifactId>json-path</artifactId>
        <version>2.6.0</version>
    </dependency>

    操作符

    操作符 说明
    $ 表示根元素
    @ 当前元素
    . or [] 子元素
    n/a 父元素
    * 通配符,表示所有的元素
    .. 选择所有符合条件的节点
    [] 迭代器标识,如数组下标
    [,] 连接操作符在XPath 结果合并其它结点集合。JSONP允许name或者数组索引。
    [start,step] 数组切片操作
    ?() 过滤表达式
    () 支持表达式计算

    函数

    函数可以在路径的尾部调用,函数的输出是路径表达式的输出,该函数的输出是由函数本身所决定的

    函数 描述 输出
    min() 提供数组的最小值 Double
    max() 提供数组的最大值 Double
    avg() 提供数组的平均值 Double
    stddev() 提供数组的标准偏差值 Double
    length() 提供数组的长度 Integer
    sum() 提供数组的总和 Double
    keys() 提供属性键(终端波浪号的替代方案 ~) Set<E>
    concat(X) 提供带有新项目的路径输出的串联版本 like input
    append(X) 向 json 路径输出数组添加一个项目 like input

    过滤操作符

    过滤器是用于过滤数组的逻辑表达式。 典型的过滤器是 [?(@.age > 18)] ,其中 @ 代表正在处理的当前项目。 可以使用逻辑运算符 && 和 || 来创建更复杂的过滤器。 字符串文字必须用单引号或双引号括起来([?(@.color == 'blue')] 或 [?(@.color == "blue")])。

    操作符 说明
    == left等于right(注意1不等于'1')
    != 不等于  
    < 小于
    <= 小于等于
    > 大于
    >= 大于等于
    =~ 匹配正则表达式[?(@.name =~ /foo.*?/i)]
    in 左边存在于右边 [?(@.size in [‘S', ‘M'])]
    nin 左边不存在于右边
    subsetof 左边是 右边 [?(@.sizes subnetof ['S', 'M', 'L'])] 的子集
    anyof 左边与右边有交集 [?(@.sizes anyof ['M', 'L'])]
    noneof 左边与右边没有交集 [?(@.sizes noneof ['M', 'L'])]
    size (数组或字符串)长度
    empty (数组或字符串)为空

    测试的json数据

    {
        "text" : "张三",
        "expensive" : 6,
        "body" : {
            "rvNoNum" : 23,
            "rvNoRecords" : [
                {
                    "score" : 4,
                    "rvAddress" : "2",
                    "consignments" : null
                },
                {
                    "score" : 8,
                    "rvAddress" : "3",
                    "consignments" : null
                }
            ]
        }
    }

    测试代码

    package jsonpathdemo;
    
    
    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.jayway.jsonpath.JsonPath;
    
    import java.io.IOException;
    import java.util.HashMap;
    import java.util.List;
    
    public class jsonpathTest {
    
        public static void main(String[] args) throws IOException {
    
            // 定义需要测试的json字符串
            String testJson = "{
    " +
                    "  "text": "张三",
    " +
                    "  "expensive": 6,
    " +
                    "  "body": {
    " +
                    "    "rvNoNum": 23,
    " +
                    "    "rvNoRecords": [{
    " +
                    "      "score": 4,
    " +
                    "      "rvAddress": "2",
    " +
                    "      "consignments": null
    " +
                    "    }, {
    " +
                    "      "score": 8,
    " +
                    "      "rvAddress": "3",
    " +
                    "      "consignments": null
    " +
                    "    }]
    " +
                    "  }
    " +
                    "}";
    
            //使用jackson对字符串反序列化为json对象
            ObjectMapper mapper = new ObjectMapper ( );
            HashMap responseJson = mapper.readValue ( testJson, HashMap.class );
    
    
            // 输出text的值
            String text = JsonPath.read(responseJson,"$.text");
            System.out.println (text );
    
            // 输出rvNoNum的值
            int rvNoNum = JsonPath.read(responseJson,"$.body.rvNoNum");
            System.out.println ( rvNoNum);
    
            //输出rvNoRecords数组的第2个值
            List<Object> rvNoRecords = JsonPath.read(responseJson,"$..rvNoRecords[1]");
            System.out.println ( rvNoRecords);
    
            //输出rvNoRecords数组的第1和第2个值
            List<Object> rvNoRecords1 = JsonPath.read(responseJson,"$..rvNoRecords[0,1]");
            System.out.println (rvNoRecords1 );
    
            //输出rvNoRecords数组中score<=expensive的所有值
            List<Object> rvNoRecords2 = JsonPath.read(responseJson,"$..rvNoRecords[?(@.score < $['expensive'])]");
            System.out.println ( rvNoRecords2);
    
            //输出rvNoRecords[0]的rvAddress值
            String rvAddress1 = JsonPath.read(responseJson, "$.body.rvNoRecords[0].rvAddress");
            System.out.println ( rvAddress1);
    
            //输出全部rvAddress的值,使用Iterator迭代
            List<String> rvAddress = JsonPath.read(responseJson,"$.body.rvNoRecords[*].rvAddress");
            System.out.println ( rvAddress);
    
            //输出rvNoRecords[*]中rvAddress== '2'的rvNoRecords
            List<Object> rvAddress2 = JsonPath.read(responseJson,"$.body.rvNoRecords[?(@.rvAddress == 2)]");
            System.out.println (rvAddress2 );
    
            //输出rvNoRecords[*]中score>5 的rvNoRecords
            List<Object> score = JsonPath.read(responseJson,"$.body.rvNoRecords[?(@.score>5)]");
            System.out.println ( score);
    
            //输出rvNoRecords[*]中含有consignments元素的rvNoRecords
            List<Double> consignments = JsonPath.read(responseJson,"$.body.rvNoRecords[?(@.consignments)]");
            System.out.println ( consignments);
    
            //输出该json中所有rvAddress的值
            List<Object> rvNoNum2 = JsonPath.read(responseJson,"$..rvAddress");
            System.out.println (rvNoNum2 );
    
            //输出rvNoRecords数组的长度
            Integer length = JsonPath.read(responseJson,"$..rvNoRecords.length()");
            System.out.println (length );
    
            //可以提前编辑一个路径,并多次使用它
            JsonPath path = JsonPath.compile("$.body.rvNoRecords[*]");
            List<Object> rvNoRecords3 = path.read(responseJson);
            System.out.println (rvNoRecords3 );
    
        }
    }

    测试结果:

    张三
    23
    [{"score":8,"rvAddress":"3","consignments":null}]
    [{"score":4,"rvAddress":"2","consignments":null},{"score":8,"rvAddress":"3","consignments":null}]
    [{"score":4,"rvAddress":"2","consignments":null}]
    2
    ["2","3"]
    [{"score":4,"rvAddress":"2","consignments":null}]
    [{"score":8,"rvAddress":"3","consignments":null}]
    [{"score":4,"rvAddress":"2","consignments":null},{"score":8,"rvAddress":"3","consignments":null}]
    ["2","3"]
    2
    [{"score":4,"rvAddress":"2","consignments":null},{"score":8,"rvAddress":"3","consignments":null}]
    知道、想到、做到、得到
  • 相关阅读:
    redis应用场景
    使用Nginx+Lua+Redis构建灰度发布环境
    Comparison method violates its general contract
    mysql+redis
    缓存技术PK:选择Memcached还是Redis?
    缓存技术PK
    菜鸟教程之工具使用(九)——Git如何进行分支的merge操作
    菜鸟教程之工具使用(八)——EGit禁止自动转换回车换行符
    菜鸟教程之工具使用(七)——从GIt上导出Maven项目
    菜鸟教程之工具使用(六)——让Maven项目直接在eclipse内部的Tomcat中运行
  • 原文地址:https://www.cnblogs.com/Durant0420/p/14963310.html
Copyright © 2011-2022 走看看