search
LoginSignup
11
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

posted at

updated at

JacksonでMix-inを使う

バージョン

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);
    }
}

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
11
Help us understand the problem. What are the problem?