Gsonでプリミティブ値を操作する
1. Overview
このチュートリアルでは、learn how to serialize and deserialize primitive values with Gson. GoogleがJSONをシリアル化および逆シリアル化するためのGsonライブラリを開発しました。 さらに、プリミティブの処理に関してGsonライブラリが持ついくつかの特定の癖について学習します。
一方、配列、コレクション、ネストされたオブジェクト、またはその他のカスタマイズを操作する必要がある場合は、serializing with Gsonとdeserializing with Gsonに関する追加のチュートリアルがあります。
2. メーベン依存
Gsonを使用するには、Gsonの依存関係をpomに追加する必要があります。
com.google.code.gson
gson
2.8.5
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"
}
例からいくつかの詳細に注意する必要があります。 手始めに、バイト値はモデルのようにビット列としてシリアル化されません。 それに加えて、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をシリアル化しようとすると、IllegalArgumentExceptionも発生します。これは、この値がJSON仕様で許可されていないためです。
同じ理由で、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になります。 It is handled poorly because in these cases an exception could be raised instead.これにより、アプリケーションを介して伝播する検出できない間違いを防ぐことができます。
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を発生させます。 This is in contrast with the NumberFormatException raised when numbers didn’t match。 変更したい場合は、custom deserializerを使用できます。
4.7. Unicode文字の逆シリアル化
Unicode文字の逆シリアル化には追加の構成は必要ないことに注意してください。
たとえば、JSON:
{"value": "\u00AE"}
結果は®文字になります。
5. 結論
これまで見てきたように、GsonはJSONおよびJavaプリミティブ型を操作する簡単な方法を提供します。 単純なプリミティブ型を扱う場合でも、注意すべき予期しない動作がいくつかあります。
この記事の完全な実装は、the GitHub projectにあります。これはEclipseベースのプロジェクトであるため、そのままインポートして実行するのは簡単です。