如何使用GSON流解析具有多个顶层对象的JSON?

nfeuvbwi  于 2023-03-18  发布在  其他
关注(0)|答案(1)|浏览(154)

我一直在寻找Gson流媒体API代码的例子,我看到了很多这样的风格:

reader.beginObject();
       while (reader.hasNext()) {

          switch(reader.peek()) {
             case NAME:
                ...
             case BEGIN_ARRAY:
                ...
             case END_ARRAY:
                ...

                }

       reader.endObject();
       reader.close();

当JSON只有一个“顶层”对象时,这段代码非常有效。hasNext()循环终止于第一个对象的末尾。我需要一个循环来处理所有对象。下面是我的JSON的一个简短示例:

{
  "meta": {
    "disclaimer": "Loren Ipsum",
    "terms": "https://myURL/terms/",
    "license": "https://myURL/license/",
    "last_updated": "2023-03-10",
    "totals": {
      "skip": 0,
      "limit": 12000,
      "total": 362818
    }
  },
  "results": [
    {"result": "value1"},
    {"result": "value2"},
    {"result": "value3"},
  ]
}

这段代码很好地处理了“ meta”对象,但从未到达“results”数组。
到处找。

m1m5dgzv

m1m5dgzv1#

在使用peek()时,通常不必处理NAMEEND_ARRAY

  • JSON指定对象由成员名和值对组成,所以你只需要在一个循环中调用hasNext(),当结果为true时调用nextName(),然后是一个值阅读方法,比如nextInt()(可能是先用peek()检查类型)。
  • 如果循环条件为hasNext(),则在循环中不会遇到END_ARRAY

JsonReader阅读JSON数组和对象的一般结构是:

jsonReader.begin###();
while (jsonReader.hasNext()) {
    ... // read values
}
jsonReader.end###();

你可以任意嵌套它。下面是一个例子,基于你的JSON数据。这个例子的重点是演示嵌套,代码不是很有用,也很冗长:

jsonReader.beginObject();
while (jsonReader.hasNext()) {
    switch (jsonReader.nextName()) {
        case "meta": {
            jsonReader.beginObject();
            while (jsonReader.hasNext()) {
                String name = jsonReader.nextName();
                switch (jsonReader.peek()) {
                    case STRING:
                        System.out.println(name + ": " + jsonReader.nextString());
                        break;
                    default:
                        jsonReader.skipValue();
                        System.out.println(name + ": <skipped>");
                        break;
                }
            }
            jsonReader.endObject();
            break;
        }
        case "results": {
            jsonReader.beginArray();
            while (jsonReader.hasNext()) {
                jsonReader.beginObject();
                while (jsonReader.hasNext()) {
                    System.out.println(jsonReader.nextName() + ": " + jsonReader.nextString());
                }
                jsonReader.endObject();
            }
            jsonReader.endArray();
            break;
        }
        default:
            throw new IllegalArgumentException("Unsupported name");
    }
}
jsonReader.endObject();

但是,在您的用例中是否真的有必要直接从JsonReader读取数据呢?如果没有必要,那么只创建与JSON数据匹配的模型类可能会更少出错(例如class Meta { String disclaimer; URL terms; ... }),并使用Gson.fromJson方法之一,将Reader作为参数。在内部,它也将以流的方式解析JSON,所以唯一的开销是,之后完整的反序列化对象存在于内存中。2但也许这正是你所需要的。

相关问题