使用哪一个跳过字段进行序列化和反序列化。
@JsonIgnore 为什么我们应该使用它,如果@Transient也从序列化和反序列化过程中跳过该字段?
答案 0 :(得分:16)
两者之间的明显区别是@Transient
被用作JPA的一部分,如果字段标记为@Transient
则忽略该字段的持久性。
其中@JsonIgnore
仅用于忽略标记字段的序列化,反序列化为JSON和从JSON反序列化。
这意味着标记为@JsonIgnore
的字段仍然可以保留在JPA持久性中,因为标记为@Transient
的字段既不会被持久化也不会被序列化,反序列化。
答案 1 :(得分:3)
我们应该区分javax.persistence.Transient
和java.beans.Transient
。正如@shazin和@Abhishek Kumar所提到的,前者向JPA发出信号,表示JPA将忽略该属性以保持持久性,并且不会影响编组。杰克逊在编组期间将后者与JsonIgnore
相同,如JacksonAnnotationIntrospector#_isIgnorable(Annotated)
所示:
protected boolean _isIgnorable(Annotated a)
{
JsonIgnore ann = _findAnnotation(a, JsonIgnore.class);
if (ann != null) {
return ann.value();
}
if (_java7Helper != null) {
Boolean b = _java7Helper.findTransient(a);
if (b != null) {
return b.booleanValue();
}
}
return false;
}
Java7SupportImpl#findTransient(Annotated)
在寻找java.beans.Transient
的地方。
答案 2 :(得分:0)
@Transient
是Java语言中transient
关键字的寓言。与变量一起使用时,永远不会序列化。
示例:
public class Person {
String name;
int age;
String password;
public Person(String name, int age, String password) {
this.name = name;
this.age = age;
this.password = password;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Transient
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
public void serializationTest() throws JsonProcessingException {
Person aPerson = new Person("Demonte", 37, "bestKeptSecret1995");
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(aPerson);
System.out.println(json);
}
通过注释getPassword()
(记住用于序列化的吸气剂) @Transient
将产生
{"name":"Demonte","age":37}
现在,如果您重新访问Person
类代码并删除@Transient
并将transient
添加到password
变量中,并且还向Jackson映射器添加了一个功能以告诉它如何处理标记为transient
transient String password;
和
mapper.configure(MapperFeature.PROPAGATE_TRANSIENT_MARKER, true);
(记住Jackson会直接使用getter而不是成员进行序列化),那么您将获得相同的输出。