Java
JSON
Jackson

JacksonでMix-inを使う

More than 3 years have passed since last update.


バージョン

jackson-databind 2.2.4

JDK 1.8.0_25


本文

JacksonでJavaのオブジェクトをJSONにシリアライズする場合、除外したい項目に@JsonIgnoreをつけたり@JsonCreatorで特定のコンストラクタをデシリアライズ時のファクトリにしたりしますが、様々な理由でアノテーションが付けられない場合もあるかと思います。


  • 外部ライブラリのクラスである

  • クラスをJackson依存にしたく無い

  • など

そういう場合、Mix-inの仕組みを使う事でクラス外からJacksonのアノテーションを付ける事ができます。


使用例(import文は除外)

シリアライズ対象クラス

public static class User {

private int userId;
private String name;
private int age;
private String password;

public User(int userId, String name, int age, String password) {
this.userId = userId;
this.name = name;
this.age = age;
this.password = password;
}

public int getUserId() {
return userId;
}

public String getName() {
return name;
}

public int getAge() {
return age;
}

public String getPassword() {
return password;
}

@Override
public String toString() {
return "User{" +
"userId=" + userId +
", name='" + name + '\'' +
", age=" + age +
", password='" + password + '\'' +
'}';
}
}

Mix-in用の抽象クラス

public static abstract class UserMixin {

/*
* JSONシリアライズ時にpasswordを除外する
*/

@JsonIgnore
abstract String getPassword();

/*
* Userの引数4つのコンストラクタをJsonCreatorにする
* (これが無いとデシリアライズできない)
*/

@JsonCreator
public UserMixin(
@JsonProperty("userId") int userId
, @JsonProperty("name") String name
, @JsonProperty("age") int age
, @JsonProperty("password") String password) {
System.out.println("mixed-in constructor.");
}
}

実際に利用するクラス

public class JacksonMixIn {

public static void main(String[] args) throws IOException {
User user = new User(1, "kamatama41", 17, "password");

/*
* 普通にシリアライズする
*
* {"userId":1,"name":"kamatama41","age":17,"password":"password"}
*/

ObjectMapper mapper = new ObjectMapper();
final String json = mapper.writeValueAsString(user);
System.out.println(json);

ObjectMapper mapper2 = new ObjectMapper();
mapper2.addMixInAnnotations(User.class, UserMixin.class);

/*
* Mix-inした状態でシリアライズする。passwordが除外される
*
* {"userId":1,"name":"kamatama41","age":17}
*/

System.out.println(mapper2.writeValueAsString(user));

/*
* Mix-inした状態でデシリアライズする。
* MixInクラスのコンストラクタは実行されない模様。
* ("mixed-in constructor."が出力されない。)
*
* User{userId=1, name='kamatama41', age=17, password='password'}
*/

final User deserializedUser = mapper2.readValue(json, User.class);
System.out.println(deserializedUser);
}
}