REST Assured 47 - Fetch Value From Nested JSON Array Using JsonNode – Jackson – At() Method

REST Assured 系列汇总 之 REST Assured 47 - Fetch Value From Nested JSON Array Using JsonNode – Jackson – At() Method

介绍

创建 POJO 类用来解析和获取一个 JSON 字符串中的值有时并不方便,特别针对那些非常长的,多层嵌套的 JSON。我们可以将 JSON 解析成树形结构更方便。

前提条件

前面我们已经解析过一个简单的 JSON Object , 嵌套的 JSON Object,和 JSON Array 成 JsonNode,参考如下:

Fetch Value From JSON Object Using JsonNode – Jackson – Get() & Path() Methods

Fetch Value From Nested JSON Object Using JsonNode – Jackson – At() Method

Fetch Value From JSON Array Using JsonNode – Jackson – Get() & Path() Methods

因为我们用到 Jackson API, 所以确保导入 Jackson Databind 依赖包。

<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.11.1</version>
</dependency>

嵌套的 JSON Array

JSON
在这里插入图片描述
树形结构表示 JSON Array
你可以用一个在线工具 来浏览上面的 JSON,呈现树型结构:
在这里插入图片描述
一个 JSON Array 可能是 JSON Objects 的集合 或 JSON arrays,如下:

[
  [
    {
    
    
      "firstName": "Amod",
      "lastName": "Mahajan",
      "age": 28,
      "isMarried": false,
      "salary": 23456.54
    },
    {
    
    
      "firstName": "Rahul",
      "lastName": "Arora",
      "age": 32,
      "isMarried": true,
      "salary": 33456.54
    }
  ],
  [
    {
    
    
      "firstName": "Amod",
      "lastName": "Mahajan",
      "age": 28,
      "isMarried": false,
      "salary": 23456.54
    },
    {
    
    
      "firstName": "Rahul",
      "lastName": "Arora",
      "age": 32,
      "isMarried": true,
      "salary": 33456.54
    }
  ]
]

反序列 deserialize 化嵌套的 JSON Array

我们用到 Jackson API 的 ObjectMapper 类,该类提供的 “readTree()” 方法负责将 JSON 内容 deserialization 反序列化成树形形式的JsonNode 集合

我们通过 JsonNode 类的 get()path() 方法来获取值,然后转换成适合的数据类型。

我们只需用一个 index 来获取一个数组的元素,这也是基于数组的概念。

拿上面嵌套的 JSON Array为例子,如果我们想要获取第一个 JSON Object 中 “type” node 的值,可以用如下方式:

// Using get method
System.out.println(jsonTree.get(0).get("firstName").asText());
System.out.println(jsonTree.get(0).get("address").get(0).get("type").asText());

如果 JSON Object 或 JSON Array 嵌套比较深,那采用上面的语句就比较长且复杂了。我们可以用 at() 来代替,传入目标 node 的 path,类似文件 path,如下:

System.out.println(jsonTree.at("/0/firstName").asText());
System.out.println(jsonTree.at("/0/address/0/type").asText());
System.out.println(jsonTree.at("/0/address/1/type").asText());

上面的 “0” 和 “1” 代表 index,实际上,它足够智能把它解析成 index 或 key。如果 node 的 key 是一个数字,如 “0” 或 “1”,它也不会抱怨。首先,会试着把它看成 index,如果不是一个 JSON Array,然后就会把它看成是一个 node 的 key。如果这个 key 不存在,将失败。

代码

import org.junit.Test;
 
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
 
public class ParseNestedJsonArrayToReadValues {
    
    
	
	@Test
	public void parseJsonArrayToReadValues() throws JsonMappingException, JsonProcessingException
	{
    
    
		String jsonArray = "[\r\n" + 
				"  {\r\n" + 
				"    \"firstName\": \"Amod\",\r\n" + 
				"    \"lastName\": \"Mahajan\",\r\n" + 
				"    \"address\": [\r\n" + 
				"      {\r\n" + 
				"        \"type\": \"Permanent\",\r\n" + 
				"        \"city\": \"Bengaluru\",\r\n" + 
				"        \"state\": \"Karnataka\"\r\n" + 
				"      },\r\n" + 
				"      {\r\n" + 
				"        \"type\": \"Communication\",\r\n" + 
				"        \"city\": \"Katihar\",\r\n" + 
				"        \"state\": \"Bihar\"\r\n" + 
				"      }\r\n" + 
				"    ]\r\n" + 
				"  },\r\n" + 
				"  {\r\n" + 
				"    \"firstName\": \"Animesh\",\r\n" + 
				"    \"lastName\": \"Prashant\",\r\n" + 
				"    \"address\": [\r\n" + 
				"      {\r\n" + 
				"        \"type\": \"Permanent\",\r\n" + 
				"        \"city\": \"Delhi\",\r\n" + 
				"        \"state\": \"Delhi\"\r\n" + 
				"      },\r\n" + 
				"      {\r\n" + 
				"        \"type\": \"Communication\",\r\n" + 
				"        \"city\": \"Indore\",\r\n" + 
				"        \"state\": \"MP\"\r\n" + 
				"      }\r\n" + 
				"    ]\r\n" + 
				"  }\r\n" + 
				"]";
		
		
		// Creating an instance of ObjectMapper class
		ObjectMapper objectMapper = new ObjectMapper();
		// Get tree representation of json
		JsonNode jsonTree = objectMapper.readTree(jsonArray);
		
		// Using get method
		System.out.println(jsonTree.get(0).get("firstName").asText());
		System.out.println(jsonTree.get(0).get("address").get(0).get("type").asText());
		
		// Using at() method
		// Printing details of first indexed node
		System.out.println(jsonTree.at("/0/firstName").asText());
		System.out.println(jsonTree.at("/0/address/0/type").asText());
		System.out.println(jsonTree.at("/0/address/1/type").asText());
		
		// Printing details of second indexed node
		System.out.println(jsonTree.at("/1/firstName").asText());
		System.out.println(jsonTree.at("/1/address/0/type").asText());
		System.out.println(jsonTree.at("/1/address/1/type").asText());
				
	}
 
}

输出

Amod
Permanent
Amod
Permanent
Communication
Animesh
Permanent
Communication

也可以试试下面的 JSON Array,其中有些 node 的 key 是数字。

[
  {
    
    
    "firstName": "Amod",
    "lastName": "Mahajan",
    "address": [
      {
    
    
        "0": "Permanent",
        "1": "Bengaluru",
        "2": "Karnataka"
      },
      {
    
    
        "0": "Communication",
        "1": "Katihar",
        "2": "Bihar"
      }
    ]
  },
  {
    
    
    "firstName": "Animesh",
    "lastName": "Prashant",
    "address": [
      {
    
    
        "0": "Permanent",
        "1": "Delhi",
        "2": "Delhi"
      },
      {
    
    
        "0": "Communication",
        "1": "Indore",
        "2": "MP"
      }
    ]
  }
]

下面的语句可以获取到 node 的值,能智能判断中数字是 index 还是 key 的名字。

System.out.println(jsonTree.at("/0/address/0/0").asText());
System.out.println(jsonTree.at("/0/address/1/0").asText());

Guess you like

Origin blog.csdn.net/wumingxiaoyao/article/details/120381254