【问题标题】:Jackson Annotations: Difference Between JsonIgnoreProperties(ignoreUnknown=true) and JsonInclude(Include.NON_EMPTY)杰克逊注解:JsonIgnoreProperties(ignoreUnknown=true) 和 JsonInclude(Include.NON_EMPTY) 之间的区别
【发布时间】:2016-12-24 15:31:33
【问题描述】:

我很好奇 Jackson 注释 @JsonIgnoreProperties(ignoreUnknown=true) 和 @JsonInclude(Include.NON_EMPTY) 在班级级别之间是否有区别?一个只是另一个的更新版本吗?谢谢!

jackson docs 声明:

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

这和只是一个空属性一样吗?

【问题讨论】:

    标签: serialization jackson deserialization


    【解决方案1】:

    简答:

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

      null 或被认为是空的不包括在内。的定义 空性是特定于数据类型的。

    长答案:

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

    【讨论】:

    • 多么好的答案。谢谢你这么彻底!
    • 有趣的是他们决定使用 JsonInclude 将其从生成的 json 中排除的名称。
    • 厉害了,把@JsonInclude(JsonInclude.Include.NON_NULL)这行放在类名上面
    • @Sebastian - 像这样读出来 -> 在反序列化时,只包含 NON_EMPTY 字段。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-29
    相关资源
    最近更新 更多