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

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

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

json解析神器 jsonpath的使用_java项目

注意: 其中他的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":