使用json-path解析json

    在我们的日常开发中,有时候需要从一个json字符串中获取一个值,或者从一段json字符串中获取到某些值,如果先使用Gson或Jackson转换成java对象在获取值,有些时候是很麻烦的,那么有没有一种根据表达式提取json中的数据的方式呢,就像使用xpath语法操作xml文件一样,答案是有的,jsonPath就是这样的一个在java中操作json的简单工具。

   jsonPath的在github上的网址如下:https://github.com/json-path/JsonPath

一、json-path中的操作符

 

二、json-path中可以使用的函数

 

三、过滤操作符

 四、表达式使用示例:

 1、数据准备

{
    "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
            },
            {
                "category": "fiction",
                "author": "Herman Melville",
                "title": "Moby Dick",
                "isbn": "0-553-21311-3",
                "price": 8.99
            },
            {
                "category": "fiction",
                "author": "J. R. R. Tolkien",
                "title": "The Lord of the Rings",
                "isbn": "0-395-19395-8",
                "price": 22.99
            }
        ],
        "bicycle": {
            "color": "red",
            "price": 19.95
        }
    },
    "expensive": 10
}

 2、示例代码



 五、在JAVA代码中使用

1、pom.xml文件中引入json-path的依赖

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

 2、编写代码

package com.huan.json;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Map;

import com.jayway.jsonpath.Configuration;
import com.jayway.jsonpath.JsonPath;
import com.jayway.jsonpath.Option;
import com.jayway.jsonpath.spi.json.JsonProvider;

/**
 * 测试jsonpath的使用
 * 
 * @描述
 * @作者 huan
 * @时间 2017年12月31日 - 下午4:34:11
 */
public class JsonPathTest {
	public static void main(String[] args) {
		String json = readJson();
		Configuration configuration = Configuration.defaultConfiguration();
		configuration = configuration.addOptions(//
				Option.DEFAULT_PATH_LEAF_TO_NULL, // 如果路径不存在则返回null,而不要抛出PathNotFoundException
				Option.SUPPRESS_EXCEPTIONS // 抑制异常的抛出,当设置了Option.ALWAYS_RETURN_LIST时返回[],否则返回null
		);
		// 如果项目中存在gson则此处可以new 一个GsonJsonProvider,那么返回对象
		// configuration.jsonProvider(new GsonJsonProvider());
		JsonProvider jsonProvider = configuration.jsonProvider();
		/**
		 * 此处预先解析json,默认请情下JsonPath.read方法每掉一次都会重新解析json,此处预先解析好就不用每次都进行解析
		 */
		Object document = jsonProvider.parse(json);
		// 1.获取所有book中的author
		List<String> authors = JsonPath.read(document, "$.store.book[*].author");
		System.out.println(authors);
		// 2.获取价格比$.expensive大的书籍
		List<Map<String, Object>> books = JsonPath.read(document, "$.store.book[?(@.price > $.expensive)]");
		System.out.println(books);
		// 3.输出一个不存在的表达式,因为存在这个选项的配置,所有返回的是Option.DEFAULT_PATH_LEAF_TO_NULL
		Object notExistsValue = JsonPath.using(configuration).parse(document).read("$.not-exists-path.path");
		System.out.println(notExistsValue);
		// 4.存在多级属性缺失
		Object object = JsonPath.using(configuration).parse(document).read("$.not-exists.path");
		System.out.println(object);
	}

	public static String readJson() {
		StringBuilder builder = new StringBuilder();
		try (InputStream is = JsonPathTest.class.getResourceAsStream("data.json"); InputStreamReader isr = new InputStreamReader(is); BufferedReader br = new BufferedReader(isr);) {
			String line;
			while (null != (line = br.readLine())) {
				builder.append(line);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return builder.toString();
	}

}

 3、结果

 

六、注意事项:

      1、在json-path的filter中 1 和 '1' 是不相等的。

      2、filter中的字符串需要使用单引号或双引号括起来

      3、JsonPath.read方法会每次进行json的解析,解决思路就是预先解析json

      4、Option中提供了一些枚举值可以控制解析的结果返回

      5、如果不想使用默认的JsonProvider则可以自己提供一个。

 

七、完整的思维导图见附件中。