使用 Jackson 将多个 json 键反序列化到一个字段

Deserialize multiple json keys to one field with Jackson

我正在调用 REST api returns 一个 json 响应,例如:

{
  "data": {
    "code": {
      "code1": {
        "name": "some-name",
        "value": "0.25"
      },
      "code2": {
        "name": "some-name2",
        "value": "0.88"
      },
      "code3": {
        "name": "some-name3",
        "value": "0.00"
      },
      "code4": {
        "name": "some-name4",
        "value": "-0.11"
      },
      "code5": {
        "name": "some-name5",
        "value": "0.99"
      }
    }
  }
}

我将其建模为以下 POJO(为清楚起见,我省略了 Data class):

@Data
@ToString
@JsonIgnoreProperties(ignoreUnknown = true)
public class Code {
    @JsonAlias({"code1", "code2", "code3", "code4", "code5"})
    private final CustomCode customCode;
}

如果“code”下只有一个对象,这就可以正常工作。在上面的示例中,从 code1 到 code5 的 CustomCode 将只有一个“codeX”对象 - 其中 X 是 1、2、3、4 或 5。

我知道我可以使用地图,但我想尽可能避免使用地图。我期待找到的是:

@Data
@ToString
@JsonIgnoreProperties(ignoreUnknown = true)
public class Code {
    @JsonAlias({"code1", "code2", "code3", "code4", "code5"})
    private final List<CustomCode> customCodeList;
}

其中 customCodeList 将保存每个 code1 到 code5 的 pojo。 所以我的问题是:Jackson 是否提供了一些 annotation/configuration 让我们能够做到这一点?

您可以像这样使用 @JsonAnySetter

public static class Code {

    private final List<CustomCode> customCodeList = new ArrayList<>();

    private static final Set<String> ALIASES = ImmutableSet.of("code1", "code2", "...");

    @JsonAnySetter
    private void set(String name, CustomCode value) {
        if (ALIASES.contains(name)) {
            customCodeList.add(value);
        }
    }
}

这种方法的一个缺点是,如果您的 Code 对象可能带有未知字段,您可能需要将 set 的第二个参数更改为 Object 并对其进行更多解析仔细。