如何使用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
相关产品推荐
相关产品推荐

