Hatena::Groupprogram

ひとり開発日記。 このページをアンテナに追加 RSSフィード

2019/01/20 (Sun)

Jacksonを使って、JSON文字列を、イミュータブルなクラスにデシリアライズしたい。

| Jacksonを使って、JSON文字列を、イミュータブルなクラスにデシリアライズしたい。 - ひとり開発日記。 を含むブックマーク はてなブックマーク - Jacksonを使って、JSON文字列を、イミュータブルなクラスにデシリアライズしたい。 - ひとり開発日記。

例えば、 以下のようなクラスがあります。

public class UserData {
    private final Long id;
    private final String email;
    private final String displayName;
    private final boolean admin;
    
    public UserData(Long id, String email, String displayName, boolean admin) {
        this.id = id;
        this.email = email;
        this.displayName = displayName;
        this.admin = admin;
    }

    // getter
}

で、JSON文字列を、JacksonのObjectMapperを使って、このクラスにデシリアライズしようとします。

    @Test
    public void testDeserialize() throws IOException {
        String json = "{\"id\":1,\"email\":\"test@example.com\",\"display_name\":\"test user no.1\",\"admin\":false}";
        ObjectMapper mapper = new ObjectMapper();
        UserData userData = mapper.readValue(json, UserData.class);
        System.out.print(userData);
    }

上記のような適当なテストケース書いて、確認しようとすると、例外が発生します。

com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `test.UserData` (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)

デフォルトコンストラクタ無いと、こんな場合はインスタンス作ることができないので、まぁ、仕方ないですね。

でも、それでもイミュータブルなクラスに変換したい時は、変換するクラスに、以下のようにアノテーションを与えてあげれば良い、とのこと。

public class UserData {
    private final Long id;
    private final String email;
    private final String displayName;
    private final boolean admin;
    
    @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
    public UserData(@JsonProperty("id") Long id, 
            @JsonProperty("email") String email, 
            @JsonProperty("display_name") String displayName, 
            @JsonProperty("admin") boolean admin) {
        this.id = id;
        this.email = email;
        this.displayName = displayName;
        this.admin = admin;
    }

    // getter
}

この後、先程のテストケースを実行すると、デシリアライズされている、と…。

トラックバック - http://program.g.hatena.ne.jp/halflite/20190120