Jackson Annotations:JsonIgnoreProperties(ignoreUnknown = true)和JsonInclude(Include.NON_EMPTY)之间的区别

rsm*_*ets 12 serialization jackson deserialization

我很奇怪Jackson注释@JsonIgnoreProperties(ignoreUnknown = true)和@JsonInclude(Include.NON_EMPTY)在类级别有什么区别?一个只是另一个的新版本吗?谢谢!

杰克逊文档指出:

ignoreUnknown属性,用于定义在反序列化期间是否可以忽略任何无法识别的属性.

这只是一个空房子吗?

Mic*_*ksa 57

简短回答:

  1. @JsonIgnoreProperties(ignoreUnknown=true)仅适用于将JSON反序列化为Java对象(POJO).如果您的POJO不包含JSON确实包含的某些属性,则会忽略它们并且不会引发任何错误.
  2. 另一方面@JsonInclude(Include.NON_EMPTY)用于POJO到JSON的序列化,它说,跳过POJO属性:

    不包括null或被认为是空的.空虚的定义是特定于数据类型的.

答案很长:

@JsonInclude

仅在序列化时使用.它表示如果有问题的属性(或所有属性)的值等于某个值(null,empty- 无论这意味着什么,或默认值),则此属性不会被序列化.

如果没有此注释,则属性值始终是序列化的.注释有助于减少传输属性的数量(当接收方不存在时,必须指定属性默认值).

例:

public class Person {
    public String firstName = "Mark";
    public String middleName;
    public String lastName = "Watney";
}

ObjectMapper mapper = new ObjectMapper();
Person p = new Person();
System.out.println(mapper.writeValueAsString(p));
Run Code Online (Sandbox Code Playgroud)

将产生以下输出:

{"firstName":"Mark","middleName":null,"lastName":"Watney"}
Run Code Online (Sandbox Code Playgroud)

但如果Person使用注释@JsonInclude(Include.NON_EMPTY),则输出中省略了middleName,因为它的值为"empty"(null在本例中):

@JsonInclude(Include.NON_EMPTY)
public static class Person {
    [....]
}
Run Code Online (Sandbox Code Playgroud)

控制台输出是: {"firstName":"Mark","lastName":"Watney"}

@JsonIgnoreProperties

用于忽略序列化和反序列化中的某些属性,无论其值如何:

防止指定字段被序列化或反序列化(即不包括在JSON输出中;或者即使它们被包括在内也被设置): @JsonIgnoreProperties({ "internalId", "secretKey" })

要无异常地忽略JSON输入中的任何未知属性: @JsonIgnoreProperties(ignoreUnknown=true)

如果JSON输入是:

{
    "firstName": "Homer",
    "middleName": "Jay",
    "lastName": "Simpson"
}
Run Code Online (Sandbox Code Playgroud)

课程是:

public class Person {
    public String firstName;
    public String lastName;
}
Run Code Online (Sandbox Code Playgroud)

反序列化mapper.readValue(json, Person.class)将产生UnrecognizedPropertyException异常:

线程"main"中的异常com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException:无法识别的字段"middleName".....

因为财产middleName不属于Person阶级.

但是如果类Person被注释@JsonIgnoreProperties(ignoreUnknown=true),则middleName在反序列化为POJO时将忽略未知属性(如).

@JsonIgnoreProperties(ignoreUnknown=true)
public class person {
    [...]
}
Run Code Online (Sandbox Code Playgroud)

另一个常见用例是禁止敏感属性的序列化,例如密码:

@JsonIgnoreProperties("password")
public static class User {
    public String login = "simpsonh";
    public String password = "D00nut";
    public String firstName = "Homer";
    public String middleName = "Jay";
    public String lastName = "Simpson";
}
Run Code Online (Sandbox Code Playgroud)

现在,如果序列化User类,输出中将省略密码:

User u = new User();
System.out.println(mapper.writeValueAsString(u));
Run Code Online (Sandbox Code Playgroud)

控制台输出: {"login":"simpsonh","firstName":"Homer","middleName":"Jay","lastName":"Simpson"}

  • 很棒的答案,谢谢你这么彻底! (5认同)
  • 惊人的答案,一切都很清楚! (2认同)
  • 多么好的答案。谢谢你这么认真! (2认同)