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"}
参考
- https://stackoverflow.com/questions/18043587/why-im-not-able-to-unwrap-and-serialize-a-java-map-using-the-jackson-java-libra
- https://github.com/FasterXML/jackson-databind/issues/171
- http://fasterxml.github.io/jackson-annotations/javadoc/2.13/com/fasterxml/jackson/annotation/JsonUnwrapped.html
- http://fasterxml.github.io/jackson-annotations/javadoc/2.13/com/fasterxml/jackson/annotation/JsonAnyGetter.html
- http://fasterxml.github.io/jackson-annotations/javadoc/2.13/com/fasterxml/jackson/annotation/JsonAnySetter.html