一、JSONPath使用需要的包
<dependency><groupId>com.jayway.jsonpath</groupId><artifactId>json-path</artifactId><version>2.4.0</version></dependency>
二、使用说明
1、JSONPath是xpath在json的应用
2、JSONPath 是参照xpath表达式来解析xml文档的方式,json数据结构通常是匿名的并且不一定需要有根元素。
3、JSONPath 用一个抽象的名字$来表示最外层对象
4、JSONPath 允许使用通配符 * 表示所以的子元素名和数组索引
三、JSONPath表达式语法
JSONPath 表达式可以使用.符号解析Json:.store.book[0].title 或者使用[]符号 ['store']['book'][0]['title']
四、测试实例(1)
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, "isbn": "0-553-21311-3" } ], "bicycle": { "color": "red", "price": 19.95 } } }
首先,读取json文件,使用commons.io的 FileUtils的readFileToString方法:
Stringpath=System.getProperty("user.dir")+File.separator+"testdata"+File.separator+"test.json"; StringjsonString=FileUtils.readFileToString(newFile(path),"utf-8"); ReadContextcontext=JsonPath.parse(json);
其次,输出book[1]的author值。有两种方法:
方法一:
JsonPath.read(json,"$.store.book[1].author"); 或context.read("$.store.book[1].author"); 输出:EvelynWaugh
方法二:
JsonPath.read(json,"$['store']['book'][1]['author']"); context.read("$['store']['book'][1]['author']"); 输出:EvelynWaugh
// 输出book[*]中category == 'reference'的book
List<Object> categorys = context.read("$.store.book[?(@.category == 'reference')]"); for(Object st: categorys){ System.out.println(st.toString()); } 输出:{category=reference, author=Nigel Rees, title=Sayings of the Century, price=8.95}
// 输出book[*]中price>10的book
List<Object>prices=context.read("$.store.book[?(@.price>10)]"); for(Objectp:prices){ System.out.println(p.toString()); } 输出:{category=fiction, author=EvelynWaugh, title=SwordofHonour, price=12.99, isbn=0-553-21311-3}
// bicycle[*]中含有color元素的bicycle
List<Object>color=context.read("$.store.bicycle[?(@.color)]"); for(Objectis :color){ System.out.println(is.toString()); } 输出://{color=red, price=19.95}
// 输出该json中所有price的值
List<Object>pp=context.read("$..price"); for(Objectp :pp){ System.out.println(p.toString()); } 输出:8.9512.9919.95List<String>authors=context.read("$.store.book[*].author"); for (Stringstr : authors) { System.out.println(str); } 输出:NigelReesEvelynWaugh
五、测试实例(2)
Demo.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}
publicclassJsonPathDemo { publicstaticvoidmain(String[] args) { Stringjson=FileUtils.readFileByLines("demo.json"); ReadContextcontext=JsonPath.parse(json); //1 返回所有nameList<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 返回第一个的nameStringname0=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 但是 不包含2List<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之前的所有数组值 [0,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 查询数组长度Integerlength01=context.read("$.result.records.length()"); //3System.out.println(length01); //15 查询list里面每个对象长度List<Integer>length02=context.read("$.result.records[?(@.all == '2' || @.name == '李四' )].length()"); //[9,8]System.out.println(length02); //16 最大值ObjectmaxV=context.read("$.max($.result.records[0].loan_type,$.result.records[1].loan_type,$.result.records[2].loan_type)"); //3.0System.out.println(maxV); //17 最小值ObjectminV=context.read("$.min($.result.records[0].loan_type,$.result.records[1].loan_type,$.result.records[2].loan_type)"); //1.0System.out.println(minV); //18 平均值doubleavgV=context.read("$.avg($.result.records[0].loan_type,$.result.records[1].loan_type,$.result.records[2].loan_type)"); //2.3333333333333335System.out.println(avgV); //19 标准差doublestddevV=context.read("$.stddev($.result.records[0].loan_type,$.result.records[1].loan_type,$.result.records[2].loan_type)"); //0.9428090415820636System.out.println(stddevV); //20 读取一个不存在的Stringhaha=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); } }
六、XPATH 和 JSONPath 获取元素的方法比较
[]在xpath表达式总是从前面的路径来操作数组,索引是从1开始。
使用JOSNPath的[]操作符操作一个对象或者数组,索引是从0开始。