JacksonでJSONを別の階層のプロパティにマップする

具体的にはJacksonでMapにデシリアライズできるJSONを、こんなクラスにマップしたいときの備忘録。

{
  "key1": "value1",
  "key2": "value2",
  ...
}
public class Response {
  private Map<String, String> map;
}

Mapに@JsonUnwrappedは使えないので、@JsonAnySetterを使う。シリアライズも必要な場合は@JsonAnyGetterも使う。

import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;

import lombok.Value;

@Value
public class Response {
    @JsonIgnore
    Map<String, String> map = new HashMap<>();

    @JsonAnySetter
    public void set(String key, String value) {
        map.put(key, value);
    }

    @JsonAnyGetter
    public Map<String, String> get() {
        return map;
    }
}
public class Main {
    public static void main(String[] args) throws IOException {
        ObjectMapper objectMapper = new ObjectMapper();
        String json = "{\"key1\":\"value1\",\"key2\":\"value2\"}";
        Response response = objectMapper.readValue(json, Response.class);
        System.out.println(response);
        System.out.println(objectMapper.writeValueAsString(response));
    }
}

実行結果

Response(map={key1=value1, key2=value2})
{"key1":"value1","key2":"value2"}

参考