如何用Jackson JSON库完整遍历并打印含无键嵌套数组的JSON文件
使用Jackson遍历JSON并提取所有键值对
核心思路
直接通过判断JsonNode的类型来处理不同节点:
- 若为ObjectNode:遍历所有字段,对每个字段的子节点递归处理
- 若为ArrayNode:遍历数组中的每个元素,直接递归处理元素(跳过数组本身,不打印无键的数组节点)
- 若为ValueNode:打印当前键值对
代码实现
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; import java.io.File; import java.io.IOException; public class JsonTraversal { public static void main(String[] args) throws IOException { ObjectMapper mapper = new ObjectMapper(); JsonNode rootNode = mapper.readTree(new File("your-json-file.json")); traverseJson(rootNode); } private static void traverseJson(JsonNode node) { traverseJson(node, null); } // 重载方法,携带当前节点的键(仅当节点是某个字段的值时才有) private static void traverseJson(JsonNode node, String key) { if (node.isObject()) { ObjectNode objectNode = (ObjectNode) node; // 遍历Object的所有字段 objectNode.fields().forEachRemaining(entry -> { traverseJson(entry.getValue(), entry.getKey()); }); } else if (node.isArray()) { ArrayNode arrayNode = (ArrayNode) node; // 遍历数组的每个元素,不需要传递键(因为数组元素无键) arrayNode.elements().forEachRemaining(element -> { traverseJson(element, null); }); } else if (node.isValueNode() && key != null) { // 仅当有键的ValueNode才打印 String valueStr; // 处理不同类型的ValueNode,保证输出格式符合预期 if (node.isBoolean()) { valueStr = String.valueOf(node.asBoolean()); } else if (node.isNumber()) { valueStr = node.asText(); } else { valueStr = "\"" + node.asText() + "\""; } System.out.printf("\"%s\": %s%n", key, valueStr); } } }
代码说明
- 类型判断:用
isObject()、isArray()、isValueNode()直接判断节点类型,比检查迭代器是否为空更直观可靠 - 递归处理:
- Object节点遍历字段,传递字段名作为键
- Array节点遍历元素,不传递键(跳过数组本身的无键节点)
- Value节点仅在有键时打印,同时根据节点类型调整输出格式(比如布尔值不加引号,字符串加引号)
- 输出格式:完全匹配你期望的样式,布尔值直接输出
false/true,字符串用双引号包裹
方案优势
- 逻辑更清晰:直接基于节点类型分支,避免判断迭代器为空带来的潜在边界问题
- 扩展性更好:后续如需处理NullNode等特殊节点,可直接添加分支
- 代码更简洁:利用Java 8的
forEachRemaining简化迭代器遍历,减少冗余代码
内容的提问来源于stack exchange,提问作者ananonymousenigma
相关产品推荐
相关产品推荐

