読者です 読者をやめる 読者になる 読者になる

覚えたら書く

IT関係のデベロッパとして日々覚えたことを書き残したいです。 twitter: @yyoshikaw

Gson

JSON Java

JavaのJSONライブラリの一つであるGsonを用いたJSONデータの取り扱いサンプルです。


Java BeansとJSON文字列の変換

Java BeansとJSON文字列の変換を行う例です。
Javaオブジェクト ⇒ JSON文字列の変換にはGson#toJsonを使用し、JSON文字列 ⇒ Javaオブジェクトの変換にはGson#fromJsonを使用します。

■変換対象のJavaオブジェクト

public class Person1 {

    private int age;

    private String name;

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append("Person1 [age=");
        builder.append(age);
        builder.append(", name=");
        builder.append(name);
        builder.append("]");
        return builder.toString();
    }
    
}


Javaオブジェクト ⇒ JSON文字列

■サンプルコード

import com.google.gson.Gson;

public class ConvertToJson {

    public static void main(String[] args) {
        Person1 p1 = new Person1();
        p1.setAge(20);
        p1.setName("Gson Taro");

        Gson gson = new Gson();
        String json = gson.toJson(p1);

        System.out.println(json);
    }
}

■実行結果(JSON文字列)

{"age":20,"name":"Gson Taro"}


JSON文字列 ⇒ Javaオブジェクト

■サンプルコード

import com.google.gson.Gson;

public class ConvertToBean {

    public static void main(String[] args) {
        String json = "{\"age\":20,\"name\":\"Gson Taro\"}";

        Gson gson = new Gson();
        Person1 p1 = gson.fromJson(json, Person1.class);

        System.out.println("Person1#toString: " + p1);
    }
}

■実行結果(toStringの内容)

Person1#toString: Person1 [age=20, name=Gson Taro]


ImmutableなクラスとJSON文字列の変換

Java BenasとJSON文字列の変換と同様に、ImmutableなクラスとJSON文字列の変換も可能です

■変換対象のJavaオブジェクト

public final class Person2 {

    private final int age;

    private final String name;

    public Person2(int age, String name) {
        this.age = age;
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public String getName() {
        return name;
    }

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append("Person2 [age=");
        builder.append(age);
        builder.append(", name=");
        builder.append(name);
        builder.append("]");
        return builder.toString();
    }
}


Javaオブジェクト ⇒ JSON文字列

■サンプルコード

import com.google.gson.Gson;

public class ConvertToJson2 {

    public static void main(String[] args) {
        Person2 p1 = new Person2(30, "Gson Hanako");

        Gson gson = new Gson();
        String json = gson.toJson(p1);

        System.out.println(json);
    }

}

■実行結果(JSON文字列)

{"age":30,"name":"Gson Hanako"}


JSON文字列 ⇒ Javaオブジェクト

■サンプルコード

import com.google.gson.Gson;

public class ConvertToObject {

    public static void main(String[] args) {
        String json = "{\"age\":30,\"name\":\"Gson Hanako\"}";

        Gson gson = new Gson();
        Person2 p1 = gson.fromJson(json, Person2.class);

        System.out.println("Person2#toString: " + p1);
    }
}

■実行結果(toStringの内容)

Person2#toString: Person2 [age=30, name=Gson Hanako]


Genericsを用いたクラスの扱い

Genericsを用いたクラスのデシリアライズを行う場合はTypeTokenクラスを利用します

Genericsを用いたクラスのデシリアライズ

■デシリアライズ対象のクラス

class Foo<T> {
  T value;
}

■デシリアライズ処理のサンプルコード

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

・・・

Gson gson = new Gson();
Foo<Bar> obj = gson.fromJson(jsonText, new TypeToken<Foo<Bar>>() {}.getType());


Listに格納されたクラスのデシリアライズを行う場合

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

・・・

Gson gson = new Gson();
List<Foo> obj = gson.fromJson(jsonText, new TypeToken<List<Foo>>() {}.getType());


Streamを利用した例

StreamからJavaオブジェクト復元

StreamからJSONデータを読み取りList型のデータを復元する例

public List<Message> readJsonStream(InputStream in) throws IOException {
    Gson gson = new Gson();
    JsonReader reader = new JsonReader(new InputStreamReader(in, "UTF-8"));
    List<Message> messages = new ArrayList<Message>();
    reader.beginArray();
    while (reader.hasNext()) {
        Message message = gson.fromJson(reader, Message.class);
        messages.add(message);
    }
    reader.endArray();
    reader.close();
    return messages;
}

StreamにJavaオブジェクトをJSON形式で出力

List型のデータをJSONデータとしてStreamに出力する例

public void writeJsonStream(OutputStream out, List<Message> messages) throws IOException {
    Gson gson = new Gson();
    JsonWriter writer = new JsonWriter(new OutputStreamWriter(out, "UTF-8"));
    // writer.setIndent("  ");   // インデントしたい場合は設定する
    writer.beginArray();
    for (Message message : messages) {
        gson.toJson(message, Message.class, writer);
    }
    writer.endArray();
    writer.close();
}


フォーマット

JSONに出力する際の項目名を好きな値にしたい

Gsonは標準ではJavaのオブジェクトのメンバ名をそのままJSONの項目名として出力しますが、
@SerializedNameアノテーション(com.google.gson.annotations.SerializedName)を対象メンバに付与することでJSON出力時の項目名を好きな値に変更することができます。

public class Person {

    private final String name;

    @SerializedName("user_id")
    private final int id;

    private final int age;

    ・・・・
}

■JSON出力結果の例

「id」ではなく「user_id」という項目名で出力されていることが分かります

{
  "name" : "yamada taro",
  "user_id" : 12345,
  "age" : 25
}


java.util.Dateのフォーマット

yyyy/MM/dd HH:mm:ss.SSS形式のJSON文字列を出力するサンプル

■サンプルコード

日付の出力フォーマットを指定しない場合と、フォーマットにyyyy/MM/dd HH:mm:ss.SSSを指定した場合の違いを確認しています

import java.util.Date;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

public class ConvertToDate {

    public static void main(String[] args) {
        DateWrapper dw = new DateWrapper();

        Gson gson = new Gson();
        String json1 = gson.toJson(dw);

        System.out.println("### normal date fromat");
        System.out.println(json1);

        System.out.println("\n--------------");

        Gson gson2 = new GsonBuilder().setDateFormat("yyyy/MM/dd HH:mm:ss.SSS").create();
        String json2 = gson2.toJson(dw);   // obj内のDate型メンバの値がyyyy/MM/dd HH:mm:ss.SSSで出力される

        System.out.println("### custom date fromat");
        System.out.println(json2);
    }


    static final class DateWrapper {

        private Date date;

        private long milisec;

        public DateWrapper() {
            this.date = new Date();
            this.milisec = date.getTime();
        }
    }
}

■実行結果

### normal date fromat
{"date":"Oct 28, 2016 11:20:11 PM","milisec":1477664411480}

--------------
### custom date fromat
{"date":"2016/10/28 23:20:11.480","milisec":1477664411480}


インデントで整形済みの文字列を出力

GsonBuilder#setPrettyPrintingを使用することでJSONが人間の目に分かりやすい形に整形されて出力されます。(デバッグ時などに有用)

■サンプルコード

整形なしの場合と整形ありの(PrettyPrintingを指定した)場合の違いを確認しています

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

public class PrettyStringSample {

    public static void main(String[] args) {
        Person1 p1 = new Person1();
        p1.setAge(20);
        p1.setName("Gson Taro");

        Gson gson = new Gson();
        String json1 = gson.toJson(p1);

        System.out.println("### Normal JSON");
        System.out.println(json1);

        System.out.println("\n--------------");

        Gson gson2 = new GsonBuilder().setPrettyPrinting().create();
        String json2 = gson2.toJson(p1);

        System.out.println("### PrettyPrinting JSON");
        System.out.println(json2);
    }
}

■実行結果

### Normal JSON
{"age":20,"name":"Gson Taro"}

--------------
### PrettyPrinting JSON
{
  "age": 20,
  "name": "Gson Taro"
}



関連エントリ