Jakarta EE 10 - Jakarta JSON Binding 3.0 変更内容まとめ


はじめに

Jakarta EE 10 で 2.0 から 3.0 へバージョンアップする Jakarta JSON Binding の変更点のまとめです。

@JsonbCreator まわりの強化が大きな点になるかと思います。


polymorphic types サポートの追加

新しく @jakarta.json.bind.annotation.JsonbTypeInfo@jakarta.json.bind.annotation.JsonbSubtype のアノテーションが追加されました。

これらのアノテーションにより、デシリアライゼーションとシリアライゼーションにおいて、多相型のサポートが可能となっています(jackson などの同アノテーションが属性名を変更して導入された形ですね)。

以下のように定義した場合、

@JsonbTypeInfo({
  @JsonbSubtype(alias = "dog", type = Dog.class)
  @JsonbSubtype(alias = "cat", type = Cat.class)
})
interface Animal {}

class Dog implements Animal {
 public String isDog = true;
}

class Cat implements Animal {
 public String isCat = true;
}

class Rat implements Animal {
 public String isRat = true;
}

以下のような出力となります。

jsonb.toJson(new Dog()); // {"@type":"dog","isDog":true}
jsonb.toJson(new Cat()); // {"@type":"cat","isCat":true}
jsonb.toJson(new Rat()); // {"isRat":true}


@JsonbCreator パラメータのオプショナル化

@JsonbCreator の全てのパラメータは、デフォルトでオプション扱いです。

パラメータを必須化するには、JSON Binding 2.1 で追加された @jakarta.json.bind.annotation.JsonbRequired を指定するか、Config::withCreatorParametersRequired を用いて必須項目に変更することが可能です(この場合、パラメータマッピングの必須項目が JSONに存在しない場合は、 JsonbException となります)。

パラメータがオプションの場合、java.util.Optional, OptionalInt, OptionalLong, OptionalDouble を指定することで、Optional.empty() が使用され、適切なデフォルト値を定義できるようになります。

なお、プリミティブ型の場合は null 値を受け取ることができないので、int の場合は 0 といった、通常の初期値として扱われることになります。

@JsonbCreator
@JsonbRequired
public ParameterTypeOptionalContainer create(
        @JsonbProperty("paramOne") Optional<String> paramOne,
        @JsonbProperty("paramTwo") Integer paramTwo) {
    return new ParameterTypeOptionalContainer(paramOne.orElse("no value"), paramTwo);
}


@JsonbTypeDeserializer, @JsonbTypeAdapter をパラメータに付与可能となった

@jakarta.json.bind.annotation.JsonbTypeDeserializer@jakarta.json.bind.annotation.JsonbTypeAdapter アノテーションのターゲットに ElementType.PARAMETER が追加されました。

これにより、@JsonbCreator でアノテートしたメソッドのパラメータに JsonbTypeDeserializer または JsonbTypeAdapter でデシリアライズを個別に指定できるようになります。


null 値の JsonValue.NULL_VALUE へのデシリアライズ

JsonValueに null 値がデシリアライズされた場合に JsonValue.NULL として扱われるようになりました。 なお、値が設定されていない場合には JsonValue.NULL は割当てられません。

JsonValueContainer unmarshalledValue = jsonb.fromJson("{ \"instance\" : null }", JsonValueContainer.class);
assertEquals("Failed to unmarshal null value to the JsonValue.NULL", JsonValue.NULL, unmarshalledValue.getInstance());


@JsonbProperty.nillable() の非推奨化

@jakarta.json.bind.annotation.JsonbProperty の属性 nillable()@Deprecated としてマークされました。

このプロパティでは、null 値を持つフィールドを JSON に直列化するかどうかを指定するもので、デフォルトは false となります。

nillable() の代わりに、 @jakarta.json.bind.annotation.JsonbNillable アノテーションを利用することになります。 これに伴い @jakarta.json.bind.annotation.JsonbNillable のターゲットとして FIELD METHOD が追加されました。

なお JsonbConfig::withNullValues により、設定レベルで null 値の直列化を行うことは、今まで通り可能です。