将多个 JSON 键反序列化为一个字段,使用 Jackson。

huangapple go评论70阅读模式
英文:

Deserialize multiple json keys to one field with Jackson

问题

以下是要翻译的代码部分:

我正在调用一个返回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;
}
这对于code下面只有一个对象的情况正常工作在上面的示例中对于code1到code5CustomCode只会有一个codeX对象其中X是1234或5

我知道我可以使用Map但如果可能的话我想避免使用Map我希望找到的是像这样的东西

@Data
@ToString
@JsonIgnoreProperties(ignoreUnknown = true)
public class Code {
    @JsonAlias({"code1", "code2", "code3", "code4", "code5"})
    private final List<CustomCode> customCodeList;
}
其中`customCodeList`将保存每个code1到code5的POJO对象
因此我的问题是Jackson是否提供了一些注释/配置允许我们实现这一点
英文:

I am calling a REST api that returns a json response like:

{
"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"
}
}
}
}

And I modeled this to the following POJO (for clarity, I omit Data class):

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

This works fine if there is only one object below "code". In the example above, with code1 to code5 CustomCode will only have one of the "codeX" objects - where X is 1, 2, 3, 4, or 5.

I know I could use a Map but I would like to avoid using a map if possible. What I look forward to find is something like:

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

Where customCodeList will hold each code1 to code5 pojos.
So my question is: does Jackson offer some annotation/configuration that allows us to accomplish this?

答案1

得分: 1

你可以像这样使用@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,并且需要更仔细地解析它。

英文:

You could make use of @JsonAnySetter like this:

public static class Code {
private final List&lt;CustomCode&gt; customCodeList = new ArrayList&lt;&gt;();
private static final Set&lt;String&gt; ALIASES = ImmutableSet.of(&quot;code1&quot;, &quot;code2&quot;, &quot;...&quot;);
@JsonAnySetter
private void set(String name, CustomCode value) {
if (ALIASES.contains(name)) {
customCodeList.add(value);
}
}
}

One downside of this approach is that if your Code object may arrive with unknown fields, you might need to change the second parameter of set to Object and parse it more carefully.

huangapple
  • 本文由 发表于 2020年10月7日 03:44:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/64232787.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定