JsonPath,读取json文档的一种DSL。
目前spring-boot-starter-test工具包也使用到了JsonPath功能。
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
<version>2.7.0</version>
<scope>compile</scope>
</dependency>
https://github.com/json-path/JsonPath
JsonPath功能可以让开发者读取json数据犹如XPath操作xml数据一样简单。
示例:json数据
代码演示:
import com.jayway.jsonpath.DocumentContext;
import com.jayway.jsonpath.JsonPath;
import net.minidev.json.JSONArray;
import org.apache.commons.io.IOUtils;
import java.io.IOException;
import java.io.InputStream;
/**
* @author 认知科技技术团队
* 微信公众号:认知科技技术团队
*/
public class JsonPathDemo {
public static void main(String[] args) throws IOException {
InputStream resourceAsStream = JsonPathDemo.class.getClassLoader().getResourceAsStream("jsonpath.json");
String json;
try (resourceAsStream) {
json = IOUtils.toString(resourceAsStream);
System.out.println(json);
}
DocumentContext documentContext = JsonPath.parse(json);
JSONArray bookJson = documentContext.read("$.store.book[*]");
System.out.println(bookJson);
}
}
我们只读取book数组元素:
JSONArray bookJson = documentContext.read("$.store.book[*]");
便可得到子json结果集:
命令行处理json数据我们可以使用https://stedolan.github.io/jq/ 工具,而且提供在线web版。
实际业务应用-renameKey功能,使得不同json转换为同一结构
比如我们对接了不同的银行z支付系统或航空订票业务系统,核心的接口返回的json内容大致相同,但是每个json中的key不一定是一样的,我们需要使用公司内部同一个model来反序列化json内容。
如果我们不使用JsonPath的renameKey功能,我们一般有以下几个解决方法:
1、外部接口json反序列化为对应的model类,然后此model类再转换为公司内部一致的同一个model;
model类之间转换可以使用半自动化工具mapstruct。
缺点也很明显,大量的model类转换类。
2、使用com.fasterxml.jackson.annotation.JsonAlias,提供多个属性别名配置;
优点很明显,只需配置属性别名即可。
使用JsonPath的renameKey功能,我们可以json的key都变长一样的。
比如上述json文档中的price,变成total-price,才符合我们的model定义,我们可以:
DocumentContext documentContext = JsonPath.parse(json);
documentContext.renameKey("$.store.book[*]", "price", "total-price");
System.out.println(documentContext.jsonString());
替换后json数据:
小结
JsonPath 工具,为我们提供了一种便利的操作json的DSL,命令行工具操作json可以使用jq。