57

假设我有以下课程:

public class Parent {
  public int age;
  @JsonUnwrapped
  public Name name;
}

生成 JSON:

{
  "age" : 18,
  "first" : "Joey",
  "last" : "Sixpack"
}

如何将其反序列化回 Parent 类?我可以使用@JsonCreator

@JsonCreator
public Parent(Map<String,String> jsonMap) {
  age = jsonMap.get("age");
  name = new Name(jsonMap.get("first"), jsonMap.get("last"));
}

但这也有效地添加@JsonIgnoreProperties(ignoreUnknown=true)到 Parent 类,因为所有属性都映射到这里。因此,如果您希望未知的 JSON 字段引发异常,则必须自己进行。此外,如果映射值可能不是字符串,则必须进行一些手动类型检查和转换。杰克逊有没有办法自动处理这个案子?

编辑: 我可能疯了,但这实际上似乎有效,尽管文档中从未明确提及:http: //fasterxml.github.io/jackson-annotations/javadoc/2.2.0/com/fasterxml/jackson/annotation/ JsonUnwrapped.html
我很确定它以前对我不起作用。尽管如此,当需要自定义逻辑来反序列化未包装的多态类型时,建议的 @JsonCreator 方法可能更受欢迎。

4

5 回答 5

37

您可以为每个字段使用@JsonCreatorwith :@JsonProperty

@JsonCreator
public Parent(@JsonProperty("age") Integer age, @JsonProperty("firstName") String firstName,
        @JsonProperty("lastName") String lastName) {
    this.age = age;
    this.name = new Name(firstName, lastName);
}

在这种情况下,Jackson 会为您进行类型检查和未知字段检查。

于 2013-05-15T16:27:05.350 回答
16

它也适用于反序列化,尽管文档中没有明确提到它,就像你说的那样。请参阅此处的反序列化单元测试以@JsonUnwrapped进行确认 - https://github.com/FasterXML/jackson-databind/blob/d2c083a6220f2875c97c29f4823d9818972511dc/src/test/java/com/fasterxml/jackson/databind/struct/TestUnwrapped.java#L138

于 2018-08-27T18:56:51.967 回答
5

@JsonUnwrapped适用于序列化和反序列化,您不需要采取任何额外的步骤。

于 2020-02-06T14:21:34.020 回答
2

尽管在 Jackson 2.13 之前的 Javadocs 中没有提到(根据 jackson-annotations#184),@JsonUnwrapped注释确实适用于反序列化和序列化,因此不需要额外的工作来支持使用注释对字段进行反序列化。

Jackson 2.13 Javadocs@JsonUnwrapped阐明注释适用于反序列化和序列化:

用于指示属性应该被序列化“解包”的注释——也就是说,如果它将被序列化为 JSON 对象,它的属性将被包含为其包含对象的属性——并且反序列化再现“缺失”结构。

[...]

当值被反序列化时,应用“包装”,以便可以读回序列化的输出。

于 2021-02-05T18:21:24.927 回答
1

对于像我一样在这里用谷歌搜索的人,试图在反序列化 unwrapepd 时解决问题Map,有一个解决方案@JsonAnySetter

public class CountryList
{

    Map<String, Country> countries = new HashMap<>();

    @JsonAnySetter
    public void setCountry(String key, Country value)
    {
        countries.put(key, value);
    }

}
于 2018-06-21T18:48:56.417 回答