我很奇怪杰克逊注释@JsonIgnoreProperties(ignoreUnknown = true)和@JsonInclude(Include.NON_EMPTY)在班级有什么区别?一个只是另一个的新版本吗?谢谢!
jackson docs表示:
ignoreUnknown属性,定义是否可以忽略 反序列化期间任何无法识别的属性。
这只是一个空房子吗?
答案 0 :(得分:41)
简短回答:
@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"}