如何从含数组的嵌套JSON中提取所有单个键值对?
提取嵌套JSON(含数组)中的所有单个键值对
需求说明
需要从包含JSON数组的嵌套JSON数据中提取所有最底层的单个键值对,忽略中间的嵌套对象和数组结构,直接输出键与对应基础类型值的关系。
示例嵌套JSON
{ "relatedquoteresponse":{ "responsepreamble":{ "responseStatus":"Passed", "statusCode":"200" }, "phone":null, "symbol":"$", "retrieverelatedquotes":[ { "quoteId":23232 }, { "quoteName":"Netally-Service" } ], "CheckStatus":{ "StatusCode":200, "responseMessage":"Found" } } }
期望输出
responseStatus : "Passed" statusCode : "200" phone: null symbol: "$" quoteId: 23232 quoteName: "Netally-Service" StatusCode: 200 responseMessage: "Found"
现有代码问题
原Jackson代码仅处理了嵌套对象结构,未对JSON数组做解析,导致整个数组被直接输出:
ObjectMapper mapper = new ObjectMapper(); JsonNode jsonNode = mapper.readTree(json); Iterator<String> iterator = jsonNode.fieldNames(); while (iterator.hasNext()) { String key = iterator.next(); printRec(jsonNode, key); } public static void printRec(JsonNode jsonNode, String key) { JsonNode node = jsonNode.get(key); if (node.isObject()) { Iterator<Map.Entry<String, JsonNode>> fields = node.fields(); fields.forEachRemaining(field -> { printRec(node, field.getKey()); if (!field.getValue().isObject()) { System.out.println(field.getKey() + " : " + field.getValue()); } }); } }
当前输出:
responseStatus : "Passed" statusCode : "200" phone: null symbol: "$" retrieverelatedquotes : [{"quoteId":23232},{"quoteName":"Netally-Service"}]
修改后的代码
在递归方法中新增数组处理逻辑,遍历数组元素并递归解析其内部结构:
ObjectMapper mapper = new ObjectMapper(); JsonNode jsonNode = mapper.readTree(json); Iterator<String> iterator = jsonNode.fieldNames(); while (iterator.hasNext()) { String key = iterator.next(); printRec(jsonNode, key); } public static void printRec(JsonNode jsonNode, String key) { JsonNode node = jsonNode.get(key); // 处理嵌套对象 if (node.isObject()) { Iterator<Map.Entry<String, JsonNode>> fields = node.fields(); fields.forEachRemaining(field -> printRec(node, field.getKey())); } // 新增:处理JSON数组 else if (node.isArray()) { for (JsonNode arrayItem : node) { if (arrayItem.isObject()) { Iterator<Map.Entry<String, JsonNode>> fields = arrayItem.fields(); fields.forEachRemaining(field -> printRec(arrayItem, field.getKey())); } // 若数组元素为基础类型,可直接输出(按需启用) // else { // System.out.println(key + " : " + arrayItem); // } } } // 处理所有基础类型值(字符串、数字、null等) else { System.out.println(key + " : " + node); } }
代码说明
- 新增
node.isArray()判断分支,遍历数组内的每个元素 - 数组元素若为对象,递归解析其内部字段;若为基础类型,可按需直接输出
- 重构基础类型值的输出逻辑,统一放到else分支,避免重复判断
修改后即可提取所有最底层的键值对,包括数组内的单个键值关系。
内容的提问来源于stack exchange,提问作者Nihar Arisal
相关产品推荐
相关产品推荐

