JsonPath:json解析神器(缓存项目中的使用)

最近要做的缓存项目中用到了jsonpath,这个工具主要是用来在多层嵌套的json中去取出对应的值。

项目介绍:

因为我们项目设计是提供一个细致到方法参数级别的缓存,中间也用到了redis,通过将项目名,类名,方法名,参数类型,已经参数的取值规则配置到redis中去,这点是通过springaop中的环绕通知去做的,获取某个包下的类,或者是jar包下,相对路径下的类等,在通过反射获取对应的方法的参数等,参数匹配的话在考虑是否取值,反正逻辑有点复杂,现在还没做完,流程不是很清楚,配置缓存规则和对应的缓存清除规则,集成到项目中去,当某个方法执行时,如果配有缓存规则,就去缓存中取出对应的数据,不然的话就继续执行,如果某个方法配了针对于另外一个方法的缓存清除规则,那个当这个方法执行的时候会把另外一个方法中的缓存清除掉。

jsonpath使用:

github:https://github.com/json-path/JsonPath

这里给出github的地址,功能介绍详细,可以直接测试并使用。

下面给出自己的测试(以下代码转载于——>>> https://blog.csdn.net/qq_20641565/article/details/77162868

pom文件引入:

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

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);
    }
}

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
}

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;
    }
}
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
nlohmann::json是一个开源的C++库,用于解析和处理JSON数据。它提供了简单易用的API,可以方便地将JSON数据解析为C++对象,并且可以轻松地将C++对象转换为JSON格式。 要使用nlohmann::json解析文件,首先需要包含头文件`#include <nlohmann/json.hpp>`。然后,可以使用`nlohmann::json`类型的对象来表示JSON数据,并使用该对象的成员函数来解析文件。 以下是解析文件的基本步骤: 1. 打开文件并读取JSON数据。 2. 使用`nlohmann::json`对象来解析JSON数据。可以使用`json::parse()`函数将JSON字符串解析为`nlohmann::json`对象。 3. 使用`nlohmann::json`对象的成员函数来访问和处理JSON数据。 下面是一个简单的示例代码,演示了如何使用nlohmann::json解析文件: ```cpp #include <iostream> #include <fstream> #include <nlohmann/json.hpp> int main() { // 打开文件并读取JSON数据 std::ifstream file("data.json"); std::string jsonData((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>()); // 使用nlohmann::json对象解析JSON数据 nlohmann::json json = nlohmann::json::parse(jsonData); // 访问和处理JSON数据 std::string name = json["name"]; int age = json["age"]; // 输出解析结果 std::cout << "Name: " << name << std::endl; std::cout << "Age: " << age << std::endl; return 0; } ``` 请注意,上述示例代码假设文件名为"data.json",并且文件包含以下JSON数据: ```json { "name": "John", "age": 25 } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值