GSONを使ったJSONの作成

JavaでGsonを使ったJSONの生成について見ていきます。GsonBuilderを使った時に動きがどう変わるのかもいくつか見ていきます。サンプルプログラムを作成し実際にどの様な結果になるか見ていきます。

基本

まずは基本的な動きを見ていきます。

String

Stringの動きをみてみます。

サンプル

Stringのサンプルプログラムです。

    @Test
    public void test_String() {
        String data = "test";
        String json = new Gson().toJson(data);
        System.out.println(json);
    }

実行結果

結果は以下の様になりました。

"test"

int / Integer

intやIntegerの動きを見てみます。

サンプル

    @Test
    public void test_int() {
        int data = 100;
        String json = new Gson().toJson(data);
        System.out.println(json);
    }
    @Test
    public void test_Integer() {
        Integer data = 200;
        String json = new Gson().toJson(data);
        System.out.println(json);
    }
    @Test
    public void test_Integer_null() {
        Integer data = null;
        String json = new Gson().toJson(data);
        System.out.println(json);
    }

実行結果

結果は以下の様になりました。

100
200
null

List

Listの動きをみてみます。

サンプル

Listのサンプルプログラムです。

    @Test
    public void test_list() {
        List<Object> data = Arrays.asList("a", "1", 1);
        String json = new Gson().toJson(data);
        System.out.println(json);
    }

実行結果

結果は以下の様になりました。

["a","1",1]

文字列で指定した1は「”1″」に、数値で指定した1は「1」となっています。

Map

Mapの動きをみてみます。

サンプル

Mapのサンプルプログラムです。

    @Test
    public void test_map() {
        Map<String, Object> data = new HashMap<>();
        data.put("a", "hoge");
        data.put("b", "100");
        data.put("c", 100);
        data.put("d", null);
        String json = new Gson().toJson(data);
        System.out.println(json);
    }

実行結果

結果は以下の様になりました。

{"a":"hoge","b":"100","c":100}

Listの時と同様、文字列の部分は「”」がつき、数値の部分は付きませんでした。また、値をnullとしたものはJSONにキーも含めて出力されませんでした。nullの扱いについては、後述しますがGsonBuilderの設定で動きが変わります。

独自クラス

独自クラスをGSONで変換した際にどの様な結果になるかをいくつか見てみます。

1つ目

サンプル

1つ目のサンプルプログラムです。

    public static class Sample_1 {

        String a = "hoge";

        String b = "fuga";

    }

    @Test
    public void test_Sample_1() {
        Gson gson = new Gson();
        Object data = new Sample_1();
        String json = gson.toJson(data);
        System.out.println(json);
    }

実行結果

結果は以下の様になりました。

{"a":"hoge","b":"fuga"}

2つ目

サンプル

2つ目のサンプルプログラムです。

    public static class Sample_2 {

        String b = "fuga";

        String a = "hoge";

    }

    @Test
    public void test_Sample_2() {
        Gson gson = new Gson();
        Object data = new Sample_2();
        String json = gson.toJson(data);
        System.out.println(json);
    }

基本的には1つ目と同じですが、フィールドの順番を逆にしています。

実行結果

結果は以下の様になりました。

{"b":"fuga","a":"hoge"}

フィールドは定義順に出力される様です。

3つ目

サンプル

3つ目のサンプルプログラムです。

    public static class Sample_3 {

        String a = "hoge";

        List<?> b = Arrays.asList("c1", "c2");

    }

    @Test
    public void test_Sample_3() {
        Gson gson = new Gson();
        Object data = new Sample_3();
        String json = gson.toJson(data);
        System.out.println(json);
    }

実行結果

結果は以下の様になりました。

{"a":"hoge","b":["c1","c2"]}

4つ目

サンプル

4つ目のサンプルプログラムです。

    public static class Sample_4 {

        String a = "hoge";

        Map<String, String> b = new LinkedHashMap<>();
        {
            b.put("c1", "d1");
            b.put("c2", "d2");
        }

    }

    @Test
    public void test_Sample_4() {
        Gson gson = new Gson();
        Object data = new Sample_4();
        String json = gson.toJson(data);
        System.out.println(json);
    }

実行結果

結果は以下の様になりました。

{"a":"hoge","b":{"c1":"d1","c2":"d2"}}

GsonBuilder

GsonBuilderを使って設定を変更した場合の動きをいくつか見ていきます。

excludeFieldsWithoutExposeAnnotation

excludeFieldsWithoutExposeAnnotationの動きをみてみます。excludeFieldsWithoutExposeAnnotationは「@Expose」のアノテーションをつけたフィールドだけ出力する様にするオプションです。

サンプル1

1つ目のサンプルプログラムです。

    public static class Sample_1 {

        String a = "hoge";

        String b = "fuga";

    }

    @Test
    public void test_Sample_1() {
        Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
        Object data = new Sample_1();
        String json = gson.toJson(data);
        System.out.println(json);
    }

実行結果1

結果は以下の様になりました。

{}

「@Expose」のついたフィールドがないので、何も出力されませんでした。

サンプル2

2つ目のサンプルプログラムです。

    public static class Sample_2 {

        String a = "hoge";

        @Expose
        String b = "fuga";

    }

    @Test
    public void test_Sample_2() {
        Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();

        Object data = new Sample_2();
        String json = gson.toJson(data);
        System.out.println(json);
    }

実行結果2

結果は以下の様になりました。「@Expose」をつけたフィールドだけが出力されています。

{"b":"fuga"}

サンプル3

3つ目のサンプルプログラムです。

    public static class Sample_3 {

        String a = "hoge";

        @Expose
        List<?> b = Arrays.asList("c1", "c2");

    }

    @Test
    public void test_Sample_3() {
        Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
        Object data = new Sample_3();
        String json = gson.toJson(data);
        System.out.println(json);
    }

実行結果3

結果は以下の様になりました。

{"b":["c1","c2"]}

サンプル4

4つ目のサンプルプログラムです。

    public static class Sample_4 {

        String a = "hoge";

        @Expose
        Map<String, String> b = new LinkedHashMap<>();
        {
            b.put("c1", "d1");
            b.put("c2", "d2");
        }

    }

    @Test
    public void test_Sample_4() {
        Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
        Object data = new Sample_4();
        String json = gson.toJson(data);
        System.out.println(json);
    }

実行結果4

結果は以下の様になりました。

{"b":{"c1":"d1","c2":"d2"}}

serializeNulls

serializeNullsの動きをみてみます。serializeNullsはシリアライズする際にnullを含めるかのオプションです。

サンプル

serializeNullsのサンプルプログラムです。

    Map<Object, String> a = new LinkedHashMap<>();
    {
        a.put("a1", "b");
        a.put("a2", null);
    }

    @Test
    public void test_1() {
        Gson gson = new Gson();
        String json = gson.toJson(a);
        System.out.println(json);
    }

    @Test
    public void test_2() {
        Gson gson = new GsonBuilder().serializeNulls().create();
        String json = gson.toJson(a);
        System.out.println(json);
    }

実行結果

結果は以下の様になりました。

{"a1":"b"}
{"a1":"b","a2":null}

serializeNullsのない方はnullの出力がなく、serializeNullsのある方はnullが出力されました。

excludeFieldsWithModifiers

excludeFieldsWithModifiersの動きをみてみます。excludeFieldsWithModifiersは除外するフィールドの種類を指定するオプションです。

サンプル

excludeFieldsWithModifiersのサンプルプログラムです。

    public static class Sample {

        String a = "hoge";

        private String b = "fuga";

    }

    @Test
    public void test_1() {
        Gson gson = new Gson();
        Object data = new Sample();
        String json = gson.toJson(data);
        System.out.println(json);
    }

    @Test
    public void test_2() {
        Gson gson = new GsonBuilder().excludeFieldsWithModifiers(Modifier.PRIVATE).create();
        Object data = new Sample();
        String json = gson.toJson(data);
        System.out.println(json);
    }

excludeFieldsWithModifiersの引数は複数指定できますが、今回は「Modifier.PRIVATE」だけを指定しています。「Modifier.PRIVATE」は「java.lang.reflect.Modifier」パッケージのフィールドです。

実行結果

結果は以下の様になりました。

{"a":"hoge","b":"fuga"}
{"a":"hoge"}

「Modifier.PRIVATE」を指定した結果、excludeFieldsWithModifiersをつけた方ではプライベートフィールドが出力から除外されました。

enableComplexMapKeySerialization

enableComplexMapKeySerializationの動きをみてみます。enableComplexMapKeySerializationはMapのキーをシリアライズするか否かのオプションです。(ちょっと理解できていない部分があるのでもしかしたら正確ではないかもしれません)

サンプル

enableComplexMapKeySerializationのサンプルプログラムです。

    static class Key {
        String a = "b";
    }

    Map<Object, String> a = new LinkedHashMap<>();
    {
        a.put(new Key(), "value");
    }

    @Test
    public void test_1() {
        Gson gson = new Gson();
        String json = gson.toJson(a);
        System.out.println(json);
    }

    @Test
    public void test_2() {
        Gson gson = new GsonBuilder().enableComplexMapKeySerialization().create();
        String json = gson.toJson(a);
        System.out.println(json);
    }

実行結果

結果は以下の様になりました。

{"net.masaki_blog.gson.base.builder.ComplexMapKeySerialization$Key@46ee7fe8":"value"}
[[{"a":"b"},"value"]]

enableComplexMapKeySerializationなしの方は、toStringの結果がJSONのキーになります。サンプルで用意したクラスではtoStringを実装していないので、デフォルトのtoStringとなっています。

enableComplexMapKeySerializationありの方は、サンプルのクラス自体のJSON形式になっています。

disableInnerClassSerialization

disableInnerClassSerializationの動きをみてみます。disableInnerClassSerializationは内部クラスを除外するかのオプションです。

サンプル

disableInnerClassSerializationのサンプルプログラムです。

    public static class Sample {

        InnerStaticClass a = new InnerStaticClass();

        InnerNonStaticClass b = new InnerNonStaticClass();

        static class InnerStaticClass {

            String c = "hoge";

        }

        class InnerNonStaticClass {

            String d = "hoge";

        }

    }

    @Test
    public void test_1() {
        Gson gson = new Gson();
        Object data = new Sample();
        String json = gson.toJson(data);
        System.out.println(json);
    }

    @Test
    public void test_2() {
        Gson gson = new GsonBuilder().disableInnerClassSerialization().create();
        Object data = new Sample();
        String json = gson.toJson(data);
        System.out.println(json);
    }

実行結果

結果は以下の様になりました。

{"a":{"c":"hoge"},"b":{"d":"hoge"}}
{"a":{"c":"hoge"}}

内部クラスが出力から除外されました。内部クラスの中でもstaticに定義した内部クラスの方は通常通り出力されています。Javaで内部クラスを定義する際、特別な理由がない限りstaticにするものなので、このオプションを使う機会はあまりないかもしれません。

作成物

今回の作成物(サンプル)は以下に置いています。

https://github.com/masaki-code/java/tree/master/gson/src/main/java/net/masaki_blog/gson/base

コメント

タイトルとURLをコピーしました