json解析神器 jsonpath的使用

转载:http://blog.csdn.net/qq_20641565/article/details/77162868

如果项目需求是从某些复杂的json里面取值进行计算,用jsonpath+IK(ik-expression)来处理十分方便,jsonpath用来取json里面的值然后用IK自带的函数进行计算,如果是特殊的计算那就自定义IK方法搞定,配置化很方便.

下面简单介绍下jsonpath的使用方法,主要测试都在JsonPathDemo类里面:

下面是一个简单的Java项目demo:

这里写图片描述

注意: 其中他的max,min,avg,stddev函数只能类似于如下处理:

//正确写法  但是感觉很鸡肋
context.read("$.avg($.result.records[0].loan_type,$.result.records[1].loan_type,$.result.records[2].loan_type)");
  • 1
  • 2
  • 1
  • 2

不能传入list 感觉比较鸡肋,如果传入list 他会报错(如下错误写法):

//这样会报错
Object maxV = context.read("$.max($.result.records[*].loan_type)");
//这样也会报错
Object maxV = context.read("$.result.records[*].loan_type.max()");
//如果json文件中是这样:"loan_type":"2",也会报错,"loan_type":2 这样才被认为是数字
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

报错信息都一样,如下:

Exception in thread "main" com.jayway.jsonpath.JsonPathException: Aggregation function attempted to calculate value using empty array
  • 1
  • 1

JsonPathDemo是一个测试demo:

public class JsonPathDemo {
    public static void main(String[] args) {
        String json = FileUtils.readFileByLines("demo.json");
        ReadContext context = JsonPath.parse(json);

        //1 返回所有name
        List<String> names = context.read("$.result.records[*].name");
        //["张三","李四","王五"]
        System.out.println(names);

        //2 返回所有数组的值
        List<Map<String, String>> objs = context.read("$.result.records[*]");
        //[{"name":"张三","pid":"500234199212121212","mobile":"18623456789","applied_at":"3","confirmed_at":"5","confirm_type":"overdue","loan_type":"1","test":"mytest","all":"2"},{"name":"李四","pid":"500234199299999999","mobile":"13098765432","applied_at":"1","confirmed_at":"","confirm_type":"overdue","loan_type":"3","all":"3"},{"name":"王五","pid":"50023415464654659","mobile":"1706454894","applied_at":"-1","confirmed_at":"","confirm_type":"overdue","loan_type":"3"}]
        System.out.println(objs);

        //3 返回第一个的name
        String name0 = context.read("$.result.records[0].name");
        //张三
        System.out.println(name0);

        //4 返回下标为0 和 2 的数组值
        List<String> name0and2 = context.read("$.result.records[0,2].name");
        //["张三","王五"]
        System.out.println(name0and2);

        //5 返回下标为0 到 下标为1的 的数组值  这里[0:2] 表示包含0 但是 不包含2
        List<String> name0to2 = context.read("$.result.records[0:2].name");
        //["张三","李四"]
        System.out.println(name0to2);

        //6 返回数组的最后两个值
        List<String> lastTwoName = context.read("$.result.records[-2:].name");
        //["李四","王五"]
        System.out.println(lastTwoName);

        //7 返回下标为1之后的所有数组值 包含下标为1的
        List<String> nameFromOne = context.read("$.result.records[1:].name");
        //["李四","王五"]
        System.out.println(nameFromOne);

        //8 返回下标为3之前的所有数组值  不包含下标为3的
        List<String> nameEndTwo = context.read("$.result.records[:3].name");
        //["张三","李四","王五"]
        System.out.println(nameEndTwo);

        //9 返回applied_at大于等于2的值
        List<Map<String, String>> records = context.read("$.result.records[?(@.applied_at >= '2')]");
        //[{"name":"张三","pid":"500234199212121212","mobile":"18623456789","applied_at":"3","confirmed_at":"5","confirm_type":"overdue","loan_type":"1","test":"mytest","all":"2"}]
        System.out.println(records);

        //10 返回name等于李四的值
        List<Map<String, String>> records0 = context.read("$.result.records[?(@.name == '李四')]");
        //[{"name":"李四","pid":"500234199299999999","mobile":"13098765432","applied_at":"1","confirmed_at":"","confirm_type":"overdue","loan_type":"3"}]
        System.out.println(records0);

        //11 返回有test属性的数组
        List<Map<String, String>> records1 = context.read("$.result.records[?(@.test)]");
        //[{"name":"张三","pid":"500234199212121212","mobile":"18623456789","applied_at":"3","confirmed_at":"5","confirm_type":"overdue","loan_type":"1","test":"mytest","all":"2"}]
        System.out.println(records1);

        //12 返回有test属性的数组
        List<String> list = context.read("$..all");
        //["1","4","2","3"]
        System.out.println(list);

        //12 以当前json的某个值为条件查询 这里ok为1 取出records数组中applied_at等于1的数组
        List<String> ok = context.read("$.result.records[?(@.applied_at == $['ok'])]");
        //["1","4","2","3"]
        System.out.println(ok);

        //13 正则匹配
        List<String> regexName = context.read("$.result.records[?(@.pid =~ /.*999/i)]");
        //[{"name":"李四","pid":"500234199299999999","mobile":"13098765432","applied_at":"1","confirmed_at":"","confirm_type":"overdue","loan_type":"3","all":"3"}]
        System.out.println(regexName);

        //14 多条件
        List<String> mobile = context.read("$.result.records[?(@.all == '2' || @.name == '李四' )].mobile");
        //["18623456789","13098765432"]
        System.out.println(mobile);

        //14 查询数组长度
        Integer length01 = context.read("$.result.records.length()");
        //3
        System.out.println(length01);

        //15 查询list里面每个对象长度
        List<Integer> length02 = context.read("$.result.records[?(@.all == '2' || @.name == '李四' )].length()");
        //[9,8]
        System.out.println(length02);

        //16 最大值
        Object maxV = context.read("$.max($.result.records[0].loan_type,$.result.records[1].loan_type,$.result.records[2].loan_type)");
        //3.0
        System.out.println(maxV);

        //17 最小值
        Object minV = context.read("$.min($.result.records[0].loan_type,$.result.records[1].loan_type,$.result.records[2].loan_type)");
        //1.0
        System.out.println(minV);

        //18 平均值
        double avgV = context.read("$.avg($.result.records[0].loan_type,$.result.records[1].loan_type,$.result.records[2].loan_type)");
        //2.3333333333333335
        System.out.println(avgV);

        //19 标准差
        double stddevV = context.read("$.stddev($.result.records[0].loan_type,$.result.records[1].loan_type,$.result.records[2].loan_type)");
        //0.9428090415820636
        System.out.println(stddevV);

        //20 读取一个不存在的
        String haha = context.read("$.result.haha");
        //抛出异常
        //Exception in thread "main" com.jayway.jsonpath.PathNotFoundException: No results for path: $['result']['haha']
        //at com.jayway.jsonpath.internal.path.EvaluationContextImpl.getValue(EvaluationContextImpl.java:133)
        //at com.jayway.jsonpath.JsonPath.read(JsonPath.java:187)
        //at com.jayway.jsonpath.internal.JsonContext.read(JsonContext.java:102)
        //at com.jayway.jsonpath.internal.JsonContext.read(JsonContext.java:89)
        //at cn.lijie.jsonpath.JsonPathDemo.main(JsonPathDemo.java:58)
        //at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        //at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        //at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        //at java.lang.reflect.Method.invoke(Method.java:498)
        //at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
        System.out.println(haha);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127

pom文件引入:

        <dependency>
            <groupId>com.jayway.jsonpath</groupId>
            <artifactId>json-path</artifactId>
            <version>2.3.0</version>
        </dependency>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

其中demo.json是一个测试json:

{
  "action": "/interface.service/xxx/queryBlackUserData",
  "all": "1",
  "result": {
    "count": 2,
    "tenant_count": 2,
    "records": [
      {
        "name": "张三",
        "pid": "500234199212121212",
        "mobile": "18623456789",
        "applied_at": "3",
        "confirmed_at": "5",
        "confirm_type": "overdue",
        "loan_type": 1,
        "test": "mytest",
        "all": "2"
      },
      {
        "name": "李四",
        "pid": "500234199299999999",
        "mobile": "13098765432",
        "applied_at": "1",
        "confirmed_at": "",
        "confirm_type": "overdue",
        "loan_type": 3,
        "all": "3"
      },
      {
        "name": "王五",
        "pid": "50023415464654659",
        "mobile": "1706454894",
        "applied_at": "-1",
        "confirmed_at": "",
        "confirm_type": "overdue",
        "loan_type": 3
      }
    ],
    "all": "4"
  },
  "code": 200,
  "subtime": "1480495123550",
  "status": "success",
  "ok": 3
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

FileUtils类是用于读取xx.json文件为字符串的json:

public class FileUtils {
    /**
     * 以行为单位读取文件,常用于读面向行的格式化文件
     */
    public static String readFileByLines(String fileName) {
        File file = new File(fileName);
        BufferedReader reader = null;
        String str = "";
        try {
            InputStream is = FileUtils.class.getClassLoader().getResourceAsStream(fileName);
            reader = new BufferedReader(new InputStreamReader(is));
            String tempString = null;
            int line = 1;
            // 一次读入一行,直到读入null为文件结束
            while ((tempString = reader.readLine()) != null) {
                // 显示行号
                str += tempString;
            }
            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e1) {
                }
            }
        }
        return str;
    }
}

 

posted @ 2017-08-17 14:29  小学生II  阅读(5354)  评论(0编辑  收藏  举报