杰克逊注解: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
它仅在序列化时使用。它表示,如果相关属性(或所有属性)的值等于某个值(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));
产生以下输出:
"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) 之间的区别