【Java】JSONに出力しないフィールドを後付で指定する
#Java #Jackson
POJO to JSON 、もしくは JSON to POJO の話。
パーサーはJacksonを利用していることを想定。
以下のようなPOJOをJSONにシリアライズする場合
code:java
public class Person {
private long id;
private String name;
private int age;
private String address;
private LocalDate birthday;
... // getter, setter
}
code:java
Person person = new Person();
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(person);
一般的には上記のような処理になると思う。
また、シリアライズ対象外にしたいフィールドがある場合、 @JsonIgnore をフィールド or getterに注釈すれば良い。
ただ、テストの時に「xxフィールドだけはシリアライズしてほしくない」みたいなケースに出くわしたときに、「テストでシリアライズ対象外にしたいから」という理由で @JsonIgnore を注釈できない。
👉例えばLocalDateやLocalDateTimeは、JSONにパースすると複数のフィールドを持つオブジェクトとして出力される。その出力されたJSONをPOJOにデシリアライズしようとしてもエラーになるので、LocalDateやLocalDateTimeはデシリアライズ対象外として欲しい場面があった。
そんな時、既存クラス(今回はPerson) に手を加えず、特定のフィールドをシリアライズしたくないという場合は、mix-inを利用する。
今回は Person の birthday をシリアライズ対象外にしたいと仮定する。
code:java
public interface PersonIgnore {
@JsonIgnore // シリアライズ対象外フィールドのgetter名に、@JsonIgnoreを注釈
LocalDate getBirthday();
}
birthday のgetterであるgetBirthday() メソッドと同じ名前のメソッドをinterface側にも定義し、@JsonIgnore を注釈する。
code:java
Person person = new Person();
ObjectMapper mapper = new ObjectMapper();
mapper.addMixIn(Person.class, PersonIgnore.class); // ObjectMapper#addMixIn を利用し、mix-inする。
String json = mapper.writeValueAsString(person);
こうすることで、既存のPOJOに手を加えずに、任意のフィールドをシリアライズ対象がとすることができる。