本格派エンジニアの工具箱

第29回 JavaオブジェクトとJSONオブジェクトの変換に便利な「Google Gson」

この記事を読むのに必要な時間:およそ 4 分

JSON→Javaオブジェクトの変換

続いて今生成したoutput2.jsonをUserオブジェクトとして読み込んでみましょう。これも先ほどと同様に,fromJson()メソッドにJsonReaderインスタンスとUserのClassインスタンスを渡して実行します。

// JSONファイルからの読み込み
try (JsonReader reader = 
     new JsonReader(new BufferedReader(new FileReader("output2.json")))) { 
    // JSONからUserオブジェクトへの変換
    User user = gson.fromJson(reader, User.class);
    System.out.println(user);
} catch (IOException ex) {
    ex.printStackTrace();
}

このコードの実行結果は次のようになり,JSONファイルからUserオブジェクトが生成できていることが確認できます。

name:
  技評
  太郎
mail:
  taro@example.co.jp

Collectionオブジェクト→JSONの変換

複数のオブジェクトからなる配列をJSON形式で作成したい場合にはどうしたらいいでしょうか。その場合はCollectionを利用します。たとえば次のコードは,Integerのデータを持ったArrayListからJSONデータを作成するサンプルです。

// JSONファイルの書き出し
try (JsonWriter writer = 
     new JsonWriter(new BufferedWriter(new FileWriter("output3.json")))) { 
    // CollectionオブジェクトからJSONへの変換
    ArrayList list = new ArrayList<>();
    list.add(1);
    list.add(2);
    list.add(3);
    gson.toJson(list, ArrayList.class, writer);
} catch (IOException ex) {
    ex.printStackTrace();
}

生成されるoutput3.jsonの中身は,次のような整数オブジェクトの配列になります。

[1,2,3]

ArrayListの中身がIntegerではなくUserオブジェクトの場合も同様です。

// JSONファイルの書き出し
try (JsonWriter writer = 
     new JsonWriter(new BufferedWriter(new FileWriter("output4.json")))) { 
    // 複数のUserからなるCollectionの生成
    Name name1 = new Name("技評", "太郎");
    User user1 = new User(name1, "taro@example.co.jp");
    Name name2 = new Name("技術", "次郎");
    User user2 = new User(name2, "jiro@example.co.jp");

    ArrayList userList = new ArrayList();
    userList.add(user1);
    userList.add(user2);

    // Userを含むCollectionオブジェクトからJSONへの変換
    gson.toJson(userList, ArrayList.class, writer);
} catch (IOException ex) {
    ex.printStackTrace();
}

この場合,output3.jsonの中身は次のようになります(見やすいように改行とスペースを追加しています)⁠UserオブジェクトもJSON形式に正しく展開されていることがわかります。

[
  {
    "name":{"first":"技評","last":"太郎"},
    "mail":"taro@example.co.jp"
  },
  {
    "name":{"first":"技術","last":"次郎"},
    "mail":"jiro@example.co.jp"
  }
]

JSON→Collectionオブジェクトの変換

最後に,上で生成したoutput3.jsonおよびoutput4.jsonから,それぞれJavaオブジェクトを生成するプログラムを作ってみます。まずはoutput3.jsonからです。注意すべき点として,Genericsを用いたArrayListは,Classインスタンスをこれまでと同じように表現できないという問題があります。そこで,TypeTokenクラスを利用します。このクラスは型引数として指定した型のjava.lang.reflect.Typeインスタンスを生成してくれまする。

得られたTypeインスタンスを次の例のようにfromJson()に渡すことで,型指定の問題をクリアすることができます。

// JSONファイルからの読み込み
try (JsonReader reader = 
     new JsonReader(new BufferedReader(new FileReader("output3.json")))) { 
    // JSONからCollectionオブジェクトへの変換
    Type type = new TypeToken>(){}.getType();
    ArrayList list = gson.fromJson(reader, type);
    for (Integer i: list) {
        System.out.println(i);
    }
} catch (IOException ex) {
    ex.printStackTrace();
}

このコードの実行結果は次のようになります。配列の要素が個別にIntegerとしてArrayListに格納されていることがわかります。

1
2
3

output4.jsonの場合も同様に,TypeTokenクラスを利用を利用することでArrayListの型を指定できるようになります。

// JSONファイルからの読み込み
try (JsonReader reader = 
     new JsonReader(new BufferedReader(new FileReader("output4.json")))) { 
    // JSONからCollectionオブジェクトへの変換
    Type type = new TypeToken>(){}.getType();
    ArrayList list = gson.fromJson(reader, type);
    for (User user: list) {
        System.out.println(user);
    }
} catch (IOException ex) {
    ex.printStackTrace();
}

このコードの実行結果は次のようになります。配列の要素になっているオブジェクトも,正しくUserオブジェクトに変換されています。

name:
  技評
  太郎
mail:
  taro@example.co.jp
name:
  技術
  次郎
mail:
  jiro@example.co.jp

このように,JSONオブジェクトとJavaオブジェクトの変換を行うという点ではGsonは極めて簡潔で便利なライブラリです。ただし,異なる型のオブジェクトを要素として持つ配列など,複雑なJSONデータの読み込みには低レベルAPIを使わなければならず,ここで紹介したようなシンプルな方法では対応できません。したがって簡潔さではGsonに,柔軟性では前回紹介したJacksonに軍配が上がりそうです。

著者プロフィール

杉山貴章(すぎやまたかあき)

ONGS Inc.所属のプログラマ兼テクニカルライター。雑誌,書籍,Webメディアで多数の著作をもつ。

著書