1.

概要

このチュートリアルでは、

Gsonを使用してプリミティブ値をシリアライズおよびデシリアライズする方法を学習します

Googleは、JSONをシリアライズおよびデシリアライズするためのGsonライブラリを開発しました。さらに、Gsonライブラリがプリミティブを処理する際に持っているいくつかの特定の奇妙な点についても学びます。

一方、配列、コレクション、入れ子になったオブジェクト、またはその他のカスタマイズを扱う必要がある場合は、https://www.baeldung.com/gson-serialization-guide[Gson]によるシリアル化およびhttps:に関する追加のチュートリアルがあります。//www.baeldung.com/gson-deserialization-guide[Gsonによるシリアル化解除]。


2 Mavenの依存関係

Gsonを使用するには、Pomにhttps://search.maven.org/search?q=g:com.google.code.gson%20AND%20a:gson[Gson]依存関係を追加する必要があります。

<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.8.5</version>
</dependency>


3プリミティブ型の直列化

Gsonによるシリアライズはとても簡単です。例として次のモデルを使用します。

public class PrimitiveBundle {
    public byte byteValue;
    public short shortValue;
    public int intValue;
    public long longValue;
    public float floatValue;
    public double doubleValue;
    public boolean booleanValue;
    public char charValue;
}

まず、いくつかのテスト値でインスタンスを初期化しましょう。

PrimitiveBundle primitiveBundle = new PrimitiveBundle();
primitiveBundle.byteValue = (byte) 0x00001111;
primitiveBundle.shortValue = (short) 3;
primitiveBundle.intValue = 3;
primitiveBundle.longValue = 3;
primitiveBundle.floatValue = 3.5f;
primitiveBundle.doubleValue = 3.5;
primitiveBundle.booleanValue = true;
primitiveBundle.charValue = 'a';

次に、それを直列化することができます。

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

最後に、直列化された結果を見ることができます。

{
   "byteValue":17,
   "shortValue":3,
   "intValue":3,
   "longValue":3,
   "floatValue":3.5,
   "doubleValue":3.5,
   "booleanValue":true,
   "charValue":"a"
}

例からいくつかの詳細に注意してください。まず第一に、byte値はモデルのようにビットの列としてシリアル化されていません。それに加えて、short、int、longの区別はありません。

また、floatとdoubleは区別されません。

もう1つ注意すべきことは、文字列が文字値を表しているということです。

実際、これらの最後の3つはGsonとは関係がありませんが、それがJSONの定義方法です。


3.1. 特別な浮動小数点値のシリアル化

Javaには、無限大を表す定数

Float.POSITIVE

INFINITY

および

NEGATIVE

INFINITY

があります。 Gsonはこれらの特別な値をシリアル化することはできません。

public class InfinityValuesExample {
    public float negativeInfinity;
    public float positiveInfinity;
}

InfinityValuesExample model = new InfinityValuesExample();
model.negativeInfinity = Float.NEGATIVE__INFINITY;
model.positiveInfinity = Float.POSITIVE__INFINITY;

Gson gson = new Gson();
gson.toJson(model);

実行しようとすると、

IllegalArgumentException

が発生します。


NaN

をシリアライズしようとすると、この値がJSON仕様で許可されていないため、

IllegalArgumentException

も発生します。

同じ理由で、

__ Double .


POSITIVE

INFINITY、NEGATIVE

INFINITY、または

NaN

をシリアル化しようとすると、

IllegalArgumentExceptionもスローされます。


4プリミティブ型のシリアル化解除

では、前の例で取得したJSON文字列をデシリアライズする方法を見てみましょう。

逆シリアル化は、シリアル化と同じくらい簡単です。

Gson gson = new Gson();
PrimitiveBundle model = gson.fromJson(json, PrimitiveBundle.class);

最後に、モデルに目的の値が含まれていることを確認できます。

assertEquals(17, model.byteValue);
assertEquals(3, model.shortValue);
assertEquals(3, model.intValue);
assertEquals(3, model.longValue);
assertEquals(3.5, model.floatValue, 0.0001);
assertEquals(3.5, model.doubleValue, 0.0001);
assertTrue(model.booleanValue);
assertEquals('a', model.charValue);


4.1. 文字列値のシリアル化解除

有効な値が文字列内に配置されると、Gsonはそれを解析して期待通りに処理します。

String json = "{\"byteValue\": \"15\", \"shortValue\": \"15\", "
  + "\"intValue\": \"15\", \"longValue\": \"15\", \"floatValue\": \"15.0\""
  + ", \"doubleValue\": \"15.0\"}";

Gson gson = new Gson();
PrimitiveBundleInitialized model = gson.fromJson(json, PrimitiveBundleInitialized.class);

assertEquals(15, model.byteValue);
assertEquals(15, model.shortValue);
assertEquals(15, model.intValue);
assertEquals(15, model.longValue);
assertEquals(15, model.floatValue, 0.0001);
assertEquals(15, model.doubleValue, 0.0001);

文字列値をブール型に逆シリアル化できないことは注目に値します。


4.2.


空の文字列値のシリアル化解除

一方、次のJSONを空の文字列で逆シリアル化してみましょう。

String json = "{\"byteValue\": \"\", \"shortValue\": \"\", "
  + "\"intValue\": \"\", \"longValue\": \"\", \"floatValue\": \"\""
  + ", \"doubleValue\": \"\"}";

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

これは

JsonSyntaxException

が発生します。プリミティブを逆シリアル化するときに空の文字列は予期されないためです


_.

_


4.3. NULL値のシリアル化解除


null

の値を持つフィールドを逆シリアル化しようとすると、Gsonはそのフィールドを無視します。たとえば、次のようなクラスがあるとします。

public class PrimitiveBundleInitialized {
    public byte byteValue = (byte) 1;
    public short shortValue = (short) 1;
    public int intValue = 1;
    public long longValue = 1L;
    public float floatValue = 1.0f;
    public double doubleValue = 1;
}

Gsonはnullフィールドを無視します。

String json = "{\"byteValue\": null, \"shortValue\": null, "
  + "\"intValue\": null, \"longValue\": null, \"floatValue\": null"
  + ", \"doubleValue\": null}";

Gson gson = new Gson();
PrimitiveBundleInitialized model = gson.fromJson(json, PrimitiveBundleInitialized.class);

assertEquals(1, model.byteValue);
assertEquals(1, model.shortValue);
assertEquals(1, model.intValue);
assertEquals(1, model.longValue);
assertEquals(1, model.floatValue, 0.0001);
assertEquals(1, model.doubleValue, 0.0001);


4.4. オーバーフローする値のシリアル化解除

これはGsonが予想外に対処した非常に興味深い事例です。逆シリアル化しようとしています。

{"value": 300}

モデルでは:

class ByteExample {
    public byte value;
}

その結果、オブジェクトの値は44になります。

これらの場合は代わりに例外が発生する可能性があるため、処理が不適切です。

これにより、検出不可能なミスがアプリケーション全体に広がるのを防ぐことができます。


4.5. 浮動小数点数のシリアル化解除

次に、次のJSONを

ByteExample

オブジェクトに逆シリアル化してみましょう。

{"value": 2.3}

ここでGsonは正しいことをし、そのサブタイプが

NumberFormatException

である

JsonSyntaxException

を発生させます。どの離散型(

byte



short




_int


、または

long_

)を使用しても、同じ結果になります。

値が「.0」で終わっている場合、Gsonは期待どおりに数値を逆シリアル化します。


4.6. 数値ブール値のシリアル化解除

場合によっては、ブール値は「true」または「false」ではなく0または1としてコード化されます。

Gsonはデフォルトでこれを許可していません。たとえば、逆シリアル化しようとすると、

{"value": 1}

モデルに:

class BooleanExample {
    public boolean value;
}

Gsonは、例外サブタイプが

IllegalStateException



JsonSyntaxException

を発生させます。

これは、数字が一致しなかったときに発生する

NumberFormatException

とは対照的です

。変更したい場合はhttps://www.baeldung.com/gson-deserialization-guide[カスタムデシリアライザ]を使用できます。


4.7. Unicode文字のシリアル化解除

Unicode文字の逆シリアル化に特別な設定が不要なことは注目に値します。

たとえば、JSON:

{"value": "\u00AE"}

®文字になります。


5結論

これまで見てきたように、GsonはJSONとJavaのプリミティブ型を扱う直接的な方法を提供します。単純なプリミティブ型を扱う場合でも、注意が必要な予期しない動作がいくつかあります。

この記事の完全な実装はhttps://github.com/eugenp/tutorials/tree/master/gson[GitHubプロジェクト]で見つけることができます – これはEclipseベースのプロジェクトなので、インポートして実行するのは簡単です。そうです。