杰克逊注解:JsonIgnoreProperties(ignoreUnknown=true) 和 JsonInclude(Include.NON_EMPTY) 之间的区别

Posted

技术标签:

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

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

jackson docs 声明:

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

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

【问题讨论】:

【参考方案1】:

简答:

    @JsonIgnoreProperties(ignoreUnknown=true) 仅适用于将 JSON 反序列化为 Java 对象 (POJO)。如果您的 POJO 不包含 JSON 确实包含的某些属性,它们将被忽略并且不会引发错误。

    另一方面,@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 字段。

以上是关于杰克逊注解:JsonIgnoreProperties(ignoreUnknown=true) 和 JsonInclude(Include.NON_EMPTY) 之间的区别的主要内容,如果未能解决你的问题,请参考以下文章

杰克逊注解:JsonIgnoreProperties(ignoreUnknown=true) 和 JsonInclude(Include.NON_EMPTY) 之间的区别

如何将 JSON 字段名称映射到不同的对象字段名称?

迈克尔·杰克逊的死因

迈科尔·杰克逊介绍

迈克尔杰克逊个人简历资料 迈克尔杰克逊怎么死的

迈克尔杰克逊简短介绍是啥?