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

如何使用Gson Streaming API解析含多个顶层对象的JSON?

Gson Streaming API 遍历多元素顶层对象解决方案

问题核心是处理顶层对象内的子元素时,没有正确维护JSON阅读器的上下文,导致遍历提前终止。现有代码的逻辑没有完整消费所有令牌,或是未在处理完子对象/数组后正确调用endObject()/endArray(),使得阅读器位置错乱,hasNext()提前返回false,无法处理后续的results数组。

以下是针对你的JSON结构的修正代码:

JsonReader reader = new JsonReader(new StringReader(yourJsonContent));
try {
    // 启动顶层对象遍历
    reader.beginObject();
    while (reader.hasNext()) {
        JsonToken token = reader.peek();
        // 顶层对象的每个元素都是键值对,先处理NAME令牌
        if (token == JsonToken.NAME) {
            String key = reader.nextName();
            switch (key) {
                case "meta":
                    // 处理meta子对象
                    reader.beginObject();
                    while (reader.hasNext()) {
                        String metaKey = reader.nextName();
                        switch (metaKey) {
                            case "disclaimer":
                                String disclaimer = reader.nextString();
                                // 这里添加disclaimer的业务处理逻辑
                                break;
                            case "terms":
                                String terms = reader.nextString();
                                // 处理terms
                                break;
                            case "license":
                                String license = reader.nextString();
                                // 处理license
                                break;
                            case "last_updated":
                                String lastUpdated = reader.nextString();
                                // 处理last_updated
                                break;
                            case "totals":
                                // 处理totals子对象
                                reader.beginObject();
                                while (reader.hasNext()) {
                                    String totalKey = reader.nextName();
                                    switch (totalKey) {
                                        case "skip":
                                            int skip = reader.nextInt();
                                            // 处理skip
                                            break;
                                        case "limit":
                                            int limit = reader.nextInt();
                                            // 处理limit
                                            break;
                                        case "total":
                                            int total = reader.nextInt();
                                            // 处理total
                                            break;
                                        default:
                                            // 跳过未知键,避免令牌阻塞
                                            reader.skipValue();
                                            break;
                                    }
                                }
                                reader.endObject();
                                break;
                            default:
                                reader.skipValue();
                                break;
                        }
                    }
                    // 结束meta对象遍历,回到顶层上下文
                    reader.endObject();
                    break;
                case "results":
                    // 处理results数组
                    reader.beginArray();
                    while (reader.hasNext()) {
                        reader.beginObject();
                        while (reader.hasNext()) {
                            String resultKey = reader.nextName();
                            if (resultKey.equals("result")) {
                                String value = reader.nextString();
                                // 处理单个result值,比如打印或存入集合
                                System.out.println("获取结果值:" + value);
                            } else {
                                reader.skipValue();
                            }
                        }
                        reader.endObject();
                    }
                    // 结束数组遍历,回到顶层上下文
                    reader.endArray();
                    break;
                default:
                    reader.skipValue();
                    break;
            }
        } else {
            // 遇到非预期令牌,直接跳过
            reader.skipValue();
        }
    }
    // 结束顶层对象遍历
    reader.endObject();
} catch (IOException e) {
    e.printStackTrace();
} finally {
    try {
        reader.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

关键注意事项

  • 每调用一次beginObject()/beginArray(),必须对应调用endObject()/endArray(),保证阅读器回到上层JSON结构的上下文
  • 遇到未知键时,必须调用skipValue()跳过,否则阅读器会停留在该位置,导致后续遍历异常
  • 处理每个键值对时,先通过nextName()获取键名,再根据值的类型(对象、数组、基本类型)进行对应处理,确保所有令牌都被正确消费

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 11:43:14