You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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);
        }
    }
}

代码说明

  1. 类型判断:用isObject()、isArray()、isValueNode()直接判断节点类型,比检查迭代器是否为空更直观可靠
  2. 递归处理:
    • Object节点遍历字段,传递字段名作为键
    • Array节点遍历元素,不传递键(跳过数组本身的无键节点)
    • Value节点仅在有键时打印,同时根据节点类型调整输出格式(比如布尔值不加引号,字符串加引号)
  3. 输出格式:完全匹配你期望的样式,布尔值直接输出false/true,字符串用双引号包裹

方案优势

  • 逻辑更清晰:直接基于节点类型分支,避免判断迭代器为空带来的潜在边界问题
  • 扩展性更好:后续如需处理NullNode等特殊节点,可直接添加分支
  • 代码更简洁:利用Java 8的forEachRemaining简化迭代器遍历,减少冗余代码

内容的提问来源于stack exchange,提问作者ananonymousenigma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 22:12:42