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 = "{\n" + " \"text\": \"张三\",\n" + " \"expensive\": 6,\n" + " \"body\": {\n" + " \"rvNoNum\": 23,\n" + " \"rvNoRecords\": [{\n" + " \"score\": 4,\n" + " \"rvAddress\": \"2\",\n" + " \"consignments\": null\n" + " }, {\n" + " \"score\": 8,\n" + " \"rvAddress\": \"3\",\n" + " \"consignments\": null\n" + " }]\n" + " }\n" + "}"; //使用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}]
    知道、想到、做到、得到
 
                    
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号