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

如何使用Gson JsonReader高效读取嵌套JSON中的DocumentList数组?

问题描述

首次使用Gson的JsonReader工具读取JSON数组内的字段值,当前用多层嵌套循环实现,代码冗余繁琐,想知道有没有更优方案直接定位访问DocumentList数组,或者直接遍历Documents对象提取字段、处理后跳转至下一个Documents对象。

当前实现代码:

streamReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8.toString());
jsonReader = new JsonReader(streamReader);
jsonReader.beginObject();
while (jsonReader.hasNext()) {
    final String name = jsonReader.nextName();
    if ("Level1".equals(name)) {
        jsonReader.beginObject();
        while (jsonReader.hasNext()) {
            final String listName = jsonReader.nextName();
            if ("DocumentList".equals(listName)) {
                jsonReader.beginArray();
                while (jsonReader.hasNext()) {
                    jsonReader.beginObject();
                    while (jsonReader.hasNext()) {
                        final String key = jsonReader.nextName();
                        if ("Documents".equals(key)) {
                            jsonReader.beginObject();
                            while (jsonReader.hasNext()) {
                                final String fieldKey = jsonReader.nextName();
                                if ("ID".equals(fieldKey)) {
                                  report.id = jsonReader.nextString();
                                } 
                                else if ("CName".equals(fieldKey)) {
                                  report.CName = jsonReader.nextString();
                                } 
                                else if ("Ext".equals(fieldKey)) {
                                  report.Ext = jsonReader.nextString();
                                } 
                                else {
                                  jsonReader.skipValue();
                                }
                            }
                            jsonReader.endObject();

                            //DO work on report (contents of "Documents")
                        } 
                        else {
                          jsonReader.skipValue();
                        }
                    }
                    jsonReader.endObject();
                }
                jsonReader.endArray();
            } 
            else {
              jsonReader.skipValue();
            }
        }
        jsonReader.endObject();
    } 
    else {
      jsonReader.skipValue();
    }
}
jsonReader.endObject();

处理的JSON示例格式:

{
  "Level1": {
    "DocumentList": [
      {
        "Documents": {
          "ID": "123",
          "CName": "name",
          "SecurityStatus": "P",
          "Ext": "abc",
          "Prefix": "pre"
        }
      },
      {
        "Documents": {
          "ID": "321",
          "CName": "name2",
          "SecurityStatus": "Q",
          "Ext": "bca",
          "Prefix": "post"
        }
      },
      {
        "Documents": {
          "ID": "456",
          "CName": "name3",
          "SecurityStatus": "S",
          "Ext": "def",
          "Prefix": "dur"
        }
      }
    ]
  }
}

解决方案

方案一:Gson对象映射(最简洁推荐)

完全避免手动嵌套解析,通过定义与JSON结构匹配的实体类,让Gson自动完成解析,代码可读性和维护性极强。

1. 定义对应实体类

// 最外层根对象
class Root {
    private Level1 Level1;

    // Level1层级对象
    static class Level1 {
        private List<DocumentItem> DocumentList;
    }

    // DocumentList数组中的单个元素
    static class DocumentItem {
        private Documents Documents;
    }

    // 目标Documents对象
    static class Documents {
        private String ID;
        private String CName;
        private String Ext;
        // 不需要的字段无需定义,Gson会自动忽略
    }
}

2. 解析并处理数据

InputStreamReader streamReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
Gson gson = new Gson();
Root root = gson.fromJson(streamReader, Root.class);

// 直接遍历Documents对象处理
for (Root.DocumentItem item : root.Level1.DocumentList) {
    Documents doc = item.Documents;
    // 提取所需字段
    String id = doc.ID;
    String cName = doc.CName;
    String ext = doc.Ext;
    
    // 处理report逻辑
    // ...
}

方案二:优化JsonReader手动解析(减少嵌套)

如果因内存限制等原因必须使用JsonReader,可以通过拆分方法来打散多层嵌套,让代码结构更清晰。

InputStreamReader streamReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
JsonReader jsonReader = new JsonReader(streamReader);

try {
    jsonReader.beginObject();
    while (jsonReader.hasNext()) {
        if ("Level1".equals(jsonReader.nextName())) {
            parseLevel1(jsonReader);
        } else {
            jsonReader.skipValue();
        }
    }
    jsonReader.endObject();
} finally {
    jsonReader.close();
}

// 解析Level1层级
private void parseLevel1(JsonReader reader) throws IOException {
    reader.beginObject();
    while (reader.hasNext()) {
        if ("DocumentList".equals(reader.nextName())) {
            parseDocumentList(reader);
        } else {
            reader.skipValue();
        }
    }
    reader.endObject();
}

// 解析DocumentList数组
private void parseDocumentList(JsonReader reader) throws IOException {
    reader.beginArray();
    while (reader.hasNext()) {
        reader.beginObject();
        while (reader.hasNext()) {
            if ("Documents".equals(reader.nextName())) {
                parseDocuments(reader);
            } else {
                reader.skipValue();
            }
        }
        reader.endObject();
    }
    reader.endArray();
}

// 解析单个Documents对象并处理
private void parseDocuments(JsonReader reader) throws IOException {
    Report report = new Report();
    reader.beginObject();
    while (reader.hasNext()) {
        switch (reader.nextName()) {
            case "ID":
                report.id = reader.nextString();
                break;
            case "CName":
                report.CName = reader.nextString();
                break;
            case "Ext":
                report.Ext = reader.nextString();
                break;
            default:
                reader.skipValue();
                break;
        }
    }
    reader.endObject();
    // 处理当前report
    // ...
}

通过将不同层级的解析逻辑拆分为独立方法,原本的嵌套结构变成线性的方法调用,代码可读性大幅提升。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 17:03:22