Jacksonである階層の属性を別の階層のObjectにマッピングする

  • このエントリーをはてなブックマークに追加

以下のJsonがあるとして、cursorhas_nextはPaginationに関するものだから、別のObjectにマッピングしたい。

{
"id": "abc",
"cursor": "next-cursor",
"has_next": true
}

普通にMappingするとこういうクラスを用意するわけだけど、

@Data
public static class MyRoot {
private String id;
private String cursor;
@JsonProperty("has_next") private boolean hasNext;
}

こういう感じの構造にマッピングしたい。

@Data
public static class MyRoot {
private String id;
private Paging paging;
}
@Data
public static class Paging {
@JsonProperty("cursor") private String cursor;
@JsonProperty("has_next") private boolean hasNext;
}

方法: @JsonUnwrappedを使う

@Data
public static class MyRoot {
private String id;
@JsonUnwrapped
private Paging paging;
}
@Data
public static class Paging {
@JsonProperty("cursor")
private String cursor;
@JsonProperty("has_next")
private boolean hasNext;
}

@Test
public static void main(String[] args) throws Exception {
String jsonString = """
{
"id": "abc",
"cursor": "next-cursor",
"has_next": true
}
""".indent(0);

ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
MyRoot root = mapper.readValue(jsonString, MyRoot.class);
System.out.println(root);
JacksonTest.MyRoot(id=abc, paging=JacksonTest.Paging(cursor=next-cursor, hasNext=true))

もし、MyRootクラスと@JsonUnwrappedされたPagingクラスに同じ属性名が存在する場合、MyRoot側に値が設定されます。