SpringBoot+JaywayJsonPath实现Json数据的DSL(按照指定节点表达式解析json获取指定数据)

发布时间:2023年12月22日

场景

若依前后端分离版手把手教你本地搭建环境并运行项目:

若依前后端分离版手把手教你本地搭建环境并运行项目_前后端分离项目本地运行-CSDN博客

在上面搭建SpringBoot项目的基础上,并且在项目中引入fastjson、hutool等所需依赖后。

Jayway JsonPath:

GitHub - json-path/JsonPath: Java JsonPath implementation

A Java DSL for reading JSON documents

需要对接第三方接口,接口返回的json数据需要解析获取数据。

可以通过配置每个返回字段的对应json数据的表达式,使其在代码中根据配置的表达式动态获取。

注:

博客:
霸道流氓气质_C#,架构之路,SpringBoot-CSDN博客

实现

1、添加项目依赖

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

2、JsonPath表达式引用JSON结构的方式与XPath表达式与XML文档结合使用的方式相同。

采用接口模拟工具模拟官方提供的示例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
??????????? },
??????????? {
??????????????? "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
}

3、快速开始

解析上面json数据中所有book节点的author字段信息

List<String> authors = JsonPath.read(body, "$.store.book[*].author");

获取第一本书的title字段

String title = JsonPath.read(body, "$['store']['book'][0]['title']");

也可以这样写

String title2 = JsonPath.read(body, "$.store.book[0].title");

获取所有book的数量

Integer number = JsonPath.read(body, "$..book.length()");

获取所有价格大于10的book

List<Map<String, Object>> expensiveBooks= JsonPath.read(body, "$.store.book[?(@.price > 10)]");

4、Json Path的语法较多,各种符号、函数、过滤等可参考官方文档。

下面记录一个读取json数据中指定结构的list数据。

首先需要读取所有book的数量,然后遍历循环,再通过配置的json数据的映射关系

获取配置的映射关系的表达式,进而解析获取对应字段的数据。

??????????? int dataSize = JsonPath.read(body, "$..book.length()");
??????????? JSONObject mapping = JSON.parseObject("{\"title\":\"$.store.book[%d].title\",\"author\":\"$.store.book[%d].author\"}");
??????????? for (int i = 0; i < dataSize; i++) {
??????????????? String titleName = mapping.containsKey("title") ? JsonPath.read(body, String.format(mapping.getString("title"), i)).toString() : null;
??????????????? System.out.println(titleName);
??????????????? String author = mapping.containsKey("author") ? JsonPath.read(body, String.format(mapping.getString("author"), i)).toString() : null;
??????????????? System.out.println(author);
??????????? }

其中JSON.parseObject是引用的fastjson。

单元测试结果

5、完整单元测试示例代码

?
import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.jayway.jsonpath.JsonPath;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.List;
import java.util.Map;

@RunWith(SpringRunner.class)
@SpringBootTest(classes = RuoYiApplication.class,webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class JsonPathTest {

??? @Test
??? public void getData() {
??????? String body = "";
??????? try {
??????????? //模拟获取接口数据
??????????? body = HttpRequest
??????????????????? .get("http://127.0.0.1:4523/m1/2858210-0-default/testJsonPath")
??????????????????? .timeout(20000)
??????????????????? .execute()
??????????????????? .body();
??????????? //获取book的所有auther
??????????? List<String> authors = JsonPath.read(body, "$.store.book[*].author");
??????????? System.out.println(authors);
??????????? //第一本book的title
??????????? String title = JsonPath.read(body, "$['store']['book'][0]['title']");
??????????? String title2 = JsonPath.read(body, "$.store.book[0].title");
??????????? System.out.println(title);
??????????? System.out.println(title2);
??????????? //所有book 的数量
??????????? Integer number = JsonPath.read(body, "$..book.length()");
??????????? System.out.println(number);
??????????? //获取所有价格大于10的book
??????????? List<Map<String, Object>> expensiveBooks= JsonPath.read(body, "$.store.book[?(@.price > 10)]");
??????????? System.out.println(expensiveBooks);

??????????? //根据配置的json数据的映射关系,获取指定表达式下的数据
??????????? int dataSize = JsonPath.read(body, "$..book.length()");
??????????? JSONObject mapping = JSON.parseObject("{\"title\":\"$.store.book[%d].title\",\"author\":\"$.store.book[%d].author\"}");
??????????? for (int i = 0; i < dataSize; i++) {
??????????????? String titleName = mapping.containsKey("title") ? JsonPath.read(body, String.format(mapping.getString("title"), i)).toString() : null;
??????????????? System.out.println(titleName);
??????????????? String author = mapping.containsKey("author") ? JsonPath.read(body, String.format(mapping.getString("author"), i)).toString() : null;
??????????????? System.out.println(author);
??????????? }
??????? } catch (Exception e) {
??????????? e.printStackTrace();
??????? }
??? }
}

?

文章来源:https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/135151754
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。