GSON には (組み合わせ可能な) 2 つの別個の API があります。1 つはシリアライゼーションとデシリアライゼーションに使用され、もう 1 つはストリーミングに使用されます。JSON のストリームをメモリ オーバーヘッドなしで、または動的構造 (静的 POJO ではなく) を使用して処理したい場合は、次のようにすることができます。
- JsonWriter を作成します (私の例では StringWriter を使用しています)。
- JsonReader を作成します。
- リーダーからのイベントを消費してライターにフィードするループを作成し、変更、追加、省略などを行う可能性があります。
ループは、考えられるすべてのイベント (10 個) のケースを持つ必要がある単一の switch ステートメントで構成されます。最も単純な例でさえ、それらすべてが含まれている必要があるため、以下のコードはかなり冗長に見えます。ただし、拡張は非常に簡単で、さらに拡張してもそれほど長くはなりません。
"test": 1 ペアを各オブジェクトに追加する例は次のようになります。
public class Whatever {
static void streamandmodify(JsonReader reader, JsonWriter writer) throws IOException {
while (true) {
JsonToken token = reader.peek();
switch (token) {
// most cases are just consume the event
// and pass an identical one to the writer
case BEGIN_ARRAY:
reader.beginArray();
writer.beginArray();
break;
case END_ARRAY:
reader.endArray();
writer.endArray();
break;
case BEGIN_OBJECT:
reader.beginObject();
writer.beginObject();
// this is where the change happens:
writer.name("test");
writer.value(1);
break;
case END_OBJECT:
reader.endObject();
writer.endObject();
break;
case NAME:
String name = reader.nextName();
writer.name(name);
break;
case STRING:
String s = reader.nextString();
writer.value(s);
break;
case NUMBER:
String n = reader.nextString();
writer.value(new BigDecimal(n));
break;
case BOOLEAN:
boolean b = reader.nextBoolean();
writer.value(b);
break;
case NULL:
reader.nextNull();
writer.nullValue();
break;
case END_DOCUMENT:
return;
}
}
}
public static void main(String[] args) throws IOException {
// just for test:
JsonReader jr = new JsonReader(new StringReader("{\"a\":1, \"b\":{\"c\":[1,2,3,{},{}]}}"));
StringWriter sw = new StringWriter();
JsonWriter jw = new JsonWriter(sw);
streamandmodify(jr, jw);
System.out.println(sw.getBuffer().toString());
}
}