本稿は JsonInclude(Include.NON_NULL)
を指定したclassのオブジェクトに対して、
値がnullでもデシリアライズ時に強制的に表示する方法についてのメモである。
背景と動機
ObjectMapperではなく、class定義でメンバごとに表示制御を行う場合、
基本的にObjectMapperに関係なく、nullメンバは表示されなくなる。
オブジェクトで指定してるのだからその動作は当然ではあるのだが、
私は開発環境向けにどうしても強制的に表示したくなった。
しかし、nullメンバを表示しない方法はたくさん見つかるが、
逆は全然情報が見つからなかった。
nullメンバを非表示
オブジェクトの全メンバに対してnullの場合に表示しないようにするには
以下のようにクラスにJsonIncludeを付与すれば良い。
https://fasterxml.github.io/jackson-annotations/javadoc/2.9/com/fasterxml/jackson/annotation/JsonInclude.Include.html
@JsonInclude(JsonInclude.Include.NON_NULL)
@Data
class MyObject {
private String name;
private Integer age;
}
このクラスのオブジェクトを値をnullにしてJSONデシリアライズすると
以下のように空のJSONになる。
{}
nullメンバを強制表示
今回の方法が必要になった経緯から説明すると、
私はデバッグ画面の入力用にメンバを含むJSONを用意したかったのだ。
正攻法で考えると初期化メソッドを持つinterfaceを作り、
それをimplementsさせれば有意な値を含めたJSONを作ることができるだろう。
しかし今回は、既に動いているアプリに対する修正を最小限にしたかったため、
"{}"をシリアライズし、そこから今度はデシリアライズして、
以下のような値を作りたいと考えた。
{
"name": null,
"age": null
}
いろいろな方法を試した結果、AnnotationIntrospectorをカスタムで用意する方法で
実現できた。
public class Hoge {
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper()
.setAnnotationIntrospector(new CustomAnnotationIntrospector());
private static class CustomAnnotationIntrospector extends JacksonAnnotationIntrospector {
@Override
public JsonInclude.Value findPropertyInclusion(Annotated a) {
return JsonInclude.Value.empty();
}
}
}
尚、上記のObjectMapperだと "{}" からのシリアライズはうまくいかないため、
私の要求を満たすにはシリアライズとデシリアライズでObjectMapperを別にする必要があった。