什么是杰克逊反序列化相当于@JsonUnwrapped?

时间:2013-05-15 16:13:02

标签: java json jackson deserialization

说我有以下课程:

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方法可能更受欢迎。

5 个答案:

答案 0 :(得分:29)

您可以将@JsonCreator@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);
}
在这种情况下,杰克逊会为你打字检查和未知的现场检查。

答案 1 :(得分:5)

@JsonUnwrapped同时用于序列化和反序列化,您无需执行任何其他步骤。

答案 2 :(得分:4)

它也确实适用于反序列化,尽管文档中并未像您所说的那样明确提及。请在此处查看@JsonUnwrapped的反序列化的单元测试以进行确认-https://github.com/FasterXML/jackson-databind/blob/d2c083a6220f2875c97c29f4823d9818972511dc/src/test/java/com/fasterxml/jackson/databind/struct/TestUnwrapped.java#L138

答案 3 :(得分:1)

尽管在现有版本的 Javadoc 中没有提到 employeeId 注释,但它确实适用于反序列化和序列化,因此不需要额外的工作来支持反序列化。

虽然文档更新尚未发布(截至 2021 年 2 月 5 日),但正在更新 Javadoc 以阐明 @JsonUnwrapped 注释适用于反序列化和序列化(根据 {{3} }).

<块引用>

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

[...]

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

答案 4 :(得分:0)

对于像我这样在此处搜索谷歌的人,在反序列化未解封的Map时尝试解决问题,有@JsonAnySetter的解决方案:

public class CountryList
{

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

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

}