首页 > 解决方案 > 使用 Jackson 将多个 json 键反序列化到一个字段

问题描述

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

{
  "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类):

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

如果“代码”下方只有一个对象,这可以正常工作。在上面的示例中,使用 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 pojos 保存在哪里。所以我的问题是:Jackson 是否提供了一些注释/配置来让我们实现这一点?

标签: javajsonjackson

解决方案


你可以@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对象可能带有未知字段,您可能需要更改 to 的第二个参数setObject更仔细地解析它。


推荐阅读