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

时间:2016-08-17 20:27:42

标签: serialization jackson deserialization

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

jackson docs表示:

  

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

这只是一个空房子吗?

1 个答案:

答案 0 :(得分:41)

简短回答:

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

      不包括

    null或被认为是空的。的定义   空虚是特定于数据类型的。

  3. 答案很长:

    <强> @JsonInclude

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

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

    示例:

    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));
    

    将产生以下输出:

    {"firstName":"Mark","middleName":null,"lastName":"Watney"}
    

    但如果Person注释为@JsonInclude(Include.NON_EMPTY),则输出中将省略middleName,因为其值为“空”(在这种情况下为null):

    @JsonInclude(Include.NON_EMPTY)
    public static class Person {
        [....]
    }
    

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

    <强> @JsonIgnoreProperties

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

      

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

         

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

    如果JSON输入是:

    {
        "firstName": "Homer",
        "middleName": "Jay",
        "lastName": "Simpson"
    }
    

    课程是:

    public class Person {
        public String firstName;
        public String lastName;
    }
    

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

      

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

    因为属性middleName不属于Person类。

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

    @JsonIgnoreProperties(ignoreUnknown=true)
    public class person {
        [...]
    }
    

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

    @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";
    }
    

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

    User u = new User();
    System.out.println(mapper.writeValueAsString(u));
    

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