You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

使用Jackson解析嵌套数组HTTP响应提取Report ID

使用Jackson提取嵌套JSON数组中的所有Report ID

我来帮你搞定这个Jackson处理嵌套JSON的问题,你遇到的核心是多层数组嵌套的遍历提取,我给你两种实用的解决方案,分别适合不同场景:

方案一:直接使用Jackson的JsonNode进行树遍历(无需POJO)

如果只是临时提取数据,不想创建一堆实体类,这种方法最快捷。你可以先把已有的edges字段对应的JSON节点拿出来,然后逐层遍历嵌套的数组:

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.ArrayList;
import java.util.List;

public class ReportIdExtractor {
    public static void main(String[] args) throws Exception {
        // 假设你已经获取到最外层的edges节点(JsonNode类型)
        JsonNode outerEdges = ...; // 这里替换成你实际拿到的edges节点

        ObjectMapper mapper = new ObjectMapper();
        List<String> reportIds = new ArrayList<>();

        // 遍历外层stixDomainEntities的edges数组
        for (JsonNode outerEdge : outerEdges) {
            // 获取node下的reports节点
            JsonNode reports = outerEdge.get("node").get("reports");
            if (reports != null && reports.has("edges")) {
                // 遍历reports的edges数组
                for (JsonNode reportEdge : reports.get("edges")) {
                    // 提取id字段并加入列表
                    JsonNode idNode = reportEdge.get("node").get("id");
                    if (idNode != null && !idNode.isNull()) {
                        reportIds.add(idNode.asText());
                    }
                }
            }
        }

        // 输出所有提取到的ID
        System.out.println("提取到的Report ID列表:");
        reportIds.forEach(System.out::println);
    }
}

这种方法的好处是灵活,不需要提前定义实体类,适合快速处理结构不固定的JSON。

方案二:通过POJO映射实现类型安全的提取(推荐长期维护场景)

如果你的JSON结构是固定的,创建对应的实体类可以让代码更清晰、类型更安全,避免空指针风险:

首先定义对应的实体类:

// 最外层的Edge(对应stixDomainEntities的edges元素)
public class StixDomainEntityEdge {
    private StixDomainNode node;

    // getter和setter
    public StixDomainNode getNode() { return node; }
    public void setNode(StixDomainNode node) { this.node = node; }
}

// StixDomainNode,包含reports字段
public class StixDomainNode {
    private ReportContainer reports;

    // getter和setter
    public ReportContainer getReports() { return reports; }
    public void setReports(ReportContainer reports) { this.reports = reports; }
}

// 包含reports的edges数组的容器
public class ReportContainer {
    private List<ReportEdge> edges;

    // getter和setter
    public List<ReportEdge> getEdges() { return edges; }
    public void setEdges(List<ReportEdge> edges) { this.edges = edges; }
}

// Report的Edge元素
public class ReportEdge {
    private ReportNode node;

    // getter和setter
    public ReportNode getNode() { return node; }
    public void setNode(ReportNode node) { this.node = node; }
}

// 最终包含ID的ReportNode
public class ReportNode {
    private String id;

    // getter和setter
    public String getId() { return id; }
    public void setId(String id) { this.id = id; }
}

然后编写提取逻辑:

import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class ReportIdExtractorWithPOJO {
    public static void main(String[] args) throws Exception {
        // 假设你已经获取到最外层edges对应的JSON字符串或JsonNode
        String outerEdgesJson = ...; // 替换成你实际的JSON内容
        ObjectMapper mapper = new ObjectMapper();

        // 反序列化为StixDomainEntityEdge的列表
        List<StixDomainEntityEdge> outerEdgesList = mapper.readValue(outerEdgesJson, 
                mapper.getTypeFactory().constructCollectionType(List.class, StixDomainEntityEdge.class));

        // 提取所有Report ID
        List<String> reportIds = new ArrayList<>();
        for (StixDomainEntityEdge outerEdge : outerEdgesList) {
            if (outerEdge.getNode() != null && outerEdge.getNode().getReports() != null) {
                List<ReportEdge> reportEdges = outerEdge.getNode().getReports().getEdges();
                if (reportEdges != null) {
                    // 遍历每个report edge提取ID
                    List<String> ids = reportEdges.stream()
                            .filter(reportEdge -> reportEdge.getNode() != null)
                            .map(reportEdge -> reportEdge.getNode().getId())
                            .filter(id -> id != null)
                            .collect(Collectors.toList());
                    reportIds.addAll(ids);
                }
            }
        }

        // 输出结果
        System.out.println("提取到的Report ID列表:");
        reportIds.forEach(System.out::println);
    }
}

这种方法的优势是类型安全,IDE会帮你检查字段名是否正确,后期JSON结构如果有小变化,修改实体类即可,代码可读性更高。

两种方案都能处理多个报告的情况,不管你的数组里有多少个元素,都会遍历提取所有的ID。

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

火山引擎 最新活动