その手の平は尻もつかめるさ

ギジュツ的な事をメーンで書く予定です

Jacksonでtop levelのpropertyを省略してMap<K, V>をserializeしたいんですけどってとき

public static class Something {
    private Map<String, String> prop;
}

をJacksonでserializeすると

{
  "prop": {
    "foo": "bar"
  }
}

と,トップレベルにpropのようなpropertyが出てくるので微妙……となるシチュエーションがまれによくあります.

で,どうすると良いかというと @JsonUnwrappedを使うという方法がまず考えられると思うんですが,これは問題があって期待通りに動かない.かれこれ6年くらいチケットがオープンになっています: @JsonUnwrapped not supported for Map-valued properties · Issue #171 · FasterXML/jackson-databind · GitHub

public static class Something {
    @JsonUnwrapped
    private Map<String, String> prop;
}

つまりこれは動かない.というわけでどうするかと言うと,チケット中にも示されているように@JsonAnyGetterを使うという方法があります.

public static class Something {
    private Map<String, String> prop;

    // workaround: https://github.com/FasterXML/jackson-databind/issues/171#issuecomment-117794241
    @JsonAnyGetter
    public Map<String, String> getProp() {
        return prop;
    }
}

このようにすると,

{
  "foo": "bar"
}

というふうにトップレベルのpropertyが省略された,MapのKey-Valueがそのままserializeされることとなります.よかったよかった.