Gsonは基本的にJSONとJavaオブジェクトを相互に変換するライブラリです。
しかし、変換のための専用クラスを作成しなくてもJSONを読み書きすることができます。
使用頻度が低いJSONや、JSONの中身がかなり不定形でクラスに切り出しにくいなどで、変換のためのクラスを作成したくないときに、使えると思います。
(結論をいえば、結局は基本的に変換専用のPOJOを作った方がよさそうです。どうしても変換専用のクラスを作りたくないなら、JSONICの方が読みやすいコードになるかもしれません)
JSON編集
下のように配列やネスト構造も作れます。
{
"outer_name": "outer_value",
"inner": {
"inner_name": "inner_value",
"inner_array": [
"abc",
123,
true
]
}
}
このJSONを出力するコードは次の通りです。
(上記の例の改行とスペースは見やすさのために加えたものです。実際は改行もスペースもありません)
Writer
を使う方法
StringWriter stringWriter = new StringWriter();
JsonWriter gsonWriter = new JsonWriter(new BufferedWriter(stringWriter));
gsonWriter.beginObject();
gsonWriter.name("outer_name").value("outer_value");
gsonWriter.name("inner");
gsonWriter.beginObject();
gsonWriter.name("inner_name").value("string_inner_value");
gsonWriter.name("inner_name").beginArray().value("abc").value("def").value("ghi").endArray();
gsonWriter.endObject();
gsonWriter.endObject();
gsonWriter.close();
String json = new String(stringWriter.getBuffer());
System.out.println(json);
JsonObject
を使う方法
JsonObject root = new JsonObject();
root.addProperty("outer_name", "outer_value");
JsonObject inner = new JsonObject();
inner.addProperty("inner_name", "inner_value");
JsonArray innerArray = new JsonArray();
innerArray.add(new JsonPrimitive("abc"));
innerArray.add(new JsonPrimitive(123));
innerArray.add(new JsonPrimitive(true));
inner.add("inner_array", innerArray);
root.add("inner", inner);
String json2 = new Gson().toJson(root);
System.out.println(json2);
JSON
読込
Reader
を使う方法
茨の道だったので敢えて紹介しません。
http://google-gson.googlecode.com/svn/trunk/gson/docs/javadocs/com/google/gson/stream/JsonReader.htmlが参考になります。
JsonObject
を使う方法
編集のところで作成したJSONを読み込んで、一番上の階層のouter_name
の値を取り出すコードは次のようになります。
JsonObject jsonObject = new Gson().fromJson(json, JsonObject.class);
String firstElement = jsonObject.get("outer_name").getAsString();
System.out.println(firstElement);
inner_array
の配列の先頭の要素を取り出すコードは次のようになります
JsonObject jsonObject = new Gson().fromJson(json, JsonObject.class);
JsonObject innter = jsonObject.get("inner").getAsJsonObject();
String firstElement = inner.getAsJsonArray("inner_array").get(0).getAsString();
System.out.println(firstElement);
感想
編集の感想
どちらの方法も、JSONの階層構造がコードの見た目にあまり現れていない点で、読みづらいですね。
特別な理由がない限り、変換専用のオブジェクトを作ろうと思いました。
もしくは上手にラッパークラスを作ればイケるかも、いや、冷静に考えるとあまりやりたくないかな?くらいの実用度だと思います。
読込の感想
編集に比べればそこそこマシだと思います。
GsonではなくJSONICというライブラリなら
StringBuilder stringBuilder = new StringBuilder();
JSONWriter jsonicWriter = new JSON().getWriter(stringBuilder);
jsonicWriter.beginObject();
jsonicWriter.name("outer_name").value("outer_value");
jsonicWriter.name("inner").value(new Object() {
public String inner_name = "inner_value";
public Object[] inner_array = { "abc", 123, true };
});
jsonicWriter.endObject();
String json = new String(stringBuilder);
System.out.println(json);
という具合にネスト構造を匿名クラスとして表現できて、
さらに、ネストのネストは、匿名クラスの中の匿名クラスで……という調子にオブジェクトの構造でJSONの構造を現せます。
JSONの構造をコードに現しやすいという点ではより優れていると思います。
(まだまだ煩雑ですが……)
JSONICの場合の読み込みはこんな感じです。
Gsonと同じく、ネストの中の配列の先頭の要素を取り出しています。
JSONReader reader = new JSON().getReader(json3);
reader.next();
Map<?, ?> map = reader.getMap();
Map jsonicInner = (Map) map.get("inner");
List array = (List) jsonicInner.get("inner_array");
System.out.println(array.get(0));
MapやListになるので、Gsonの場合よりもわかりやすい感じがしますね。
結論
- 基本に忠実に、POJO <-> JSON で変換した方がよさげ
- どうしても変換専用のクラスを作りたくないならGsonよりもJSONICの方が可読性が高い気がする