基本型→JSONの変換
前回は2回にわたってJavaプログラムでJSONデータを扱うための「Jackson Java JSON-processor」を紹介しました。今回はJSONデータを扱うもう1つのJavaライブラリ「Google Gson」を紹介します。Gsonの特徴は、JavaオブジェクトとJSONオブジェクトの変換を、シンプルなコードで行うことができる点です。字句解析を行えるような低レベルのAPIも備えていますが、それよりもオブジェクト変換の簡潔さに注力しているあたりがJacksonとの大きな違いと言えます。
Gsonはこのページよりダウンロードすることができます。「google-gson-2.1-release.zip 」をダウンロードして解凍し、中のjarファイルをクラスパスに含めて使用します。
Gsonを使う場合に重要なのは、GsonクラスのtoJson()メソッドとfromJson()メソッドの2つだけです。名前からも推察できるように、toJson()はJavaオブジェクトをJSONオブジェクトに変換するためのメソッド、fromJson()はおの逆にJSONからJavaへ変換するためのメソッドです。
まずは整数や文字列をJSON形式で出力してみましょう。次のようにGsonインスタンスを生成し、toJson()メソッドに整数や文字列を渡すと、JSON形式のテキストが返されます。配列も同様で、基本型の配列であればそのまま渡すだけでJSON配列に変換してくれます。
toJson()メソッドでJSONデータを直接ファイルに出力することもできます。その場合、メソッドの第2引数にJsonWriterインスタンスを渡せば問題ありません。JsonWriterのコンストラクタには任意のWriterインスタンスを指定できるので、下記のようにここにFileWriterを渡せばいいわけです。ただし、JsonWriterを引数に取るtoJson()メソッドでは基本型を直接扱うことができないので、代わりにJsonPrimitiveクラスを使用する必要があります。
このコードを実行すると、output1.jsonとして次のようなJSONデータが生成されます。
JSON→基本型の変換
JSON形式のデータをJavaオブジェクトとして読み込むにはfromJson()メソッドを利用します。その場合、引数にはJSON形式のStringオブジェクトと、変換後のJavaオブジェクトのClassインスタンスをセットで渡す必要があります。データ基本型や文字列、基本型の配列であれば、次のような具合です。
ファイルから読み込む場合には、次のようにJsonReaderクラスを利用します。
Javaオブジェクト→JSONの変換
次に、任意のJavaオブジェクトをJSON形式に変換して出力してみましょう。ここでは例として、次のようなNameクラスとUserクラスを使用します。NameオブジェクトがUserオブジェクトの要素になっている形です。
この場合も、先ほどと同様にtoJson()メソッドを利用します。ただし、今度は次のように対象となるJavaオブジェクトのClassインスタンスをセットで渡す必要があります。
このコードを実行すると、output2.jsonとして次のようなJSONデータが生成されます。オブジェクトのネストも表現できていることがわかります。
JSON→Javaオブジェクトの変換
続いて今生成したoutput2.jsonをUserオブジェクトとして読み込んでみましょう。これも先ほどと同様に、fromJson()メソッドにJsonReaderインスタンスとUserのClassインスタンスを渡して実行します。
このコードの実行結果は次のようになり、JSONファイルからUserオブジェクトが生成できていることが確認できます。
Collectionオブジェクト→JSONの変換
複数のオブジェクトからなる配列をJSON形式で作成したい場合にはどうしたらいいでしょうか。その場合はCollectionを利用します。たとえば次のコードは、Integerのデータを持ったArrayListからJSONデータを作成するサンプルです。
生成されるoutput3.jsonの中身は、次のような整数オブジェクトの配列になります。
ArrayListの中身がIntegerではなくUserオブジェクトの場合も同様です。
この場合、output3.jsonの中身は次のようになります(見やすいように改行とスペースを追加しています)。UserオブジェクトもJSON形式に正しく展開されていることがわかります。
JSON→Collectionオブジェクトの変換
最後に、上で生成したoutput3.jsonおよびoutput4.jsonから、それぞれJavaオブジェクトを生成するプログラムを作ってみます。まずはoutput3.jsonからです。注意すべき点として、Genericsを用いたArrayListは、Classインスタンスをこれまでと同じように表現できないという問題があります。そこで、TypeTokenクラスを利用します。このクラスは型引数として指定した型のjava.lang.reflect.Typeインスタンスを生成してくれまする。
得られたTypeインスタンスを次の例のようにfromJson()に渡すことで、型指定の問題をクリアすることができます。
このコードの実行結果は次のようになります。配列の要素が個別にIntegerとしてArrayListに格納されていることがわかります。
output4.jsonの場合も同様に、TypeTokenクラスを利用を利用することでArrayListの型を指定できるようになります。
このコードの実行結果は次のようになります。配列の要素になっているオブジェクトも、正しくUserオブジェクトに変換されています。
このように、JSONオブジェクトとJavaオブジェクトの変換を行うという点ではGsonは極めて簡潔で便利なライブラリです。ただし、異なる型のオブジェクトを要素として持つ配列など、複雑なJSONデータの読み込みには低レベルAPIを使わなければならず、ここで紹介したようなシンプルな方法では対応できません。したがって簡潔さではGsonに、柔軟性では前回紹介したJacksonに軍配が上がりそうです。