在序列化和反序列化中,选用哪一种方法来跳过字段。
@JsonIgnore为什么要使用它,如果@Transient也可以跳过序列化和反序列化过程中的字段?
@Transient
是用作 JPA 的一部分,如果将字段标记为@Transient
,则可以忽略该字段不进行持久化。@JsonIgnore
仅用于忽略标记字段的序列化和反序列化,即使使用 JPA 持久化,标记为 @JsonIgnore
的字段仍然可以持久化,但使用@Transient
标记的字段既不会被持久化也不会进行序列化或反序列化。javax.persistence.Transient
和 java.beans.Transient
。前者表示JPA忽略属性的持久性,不影响编组。Jackson在编组期间将后者视为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
。
@javax.persistence.Transient
注释时与处理方法上的@java.beans.Transient
注释方式相同 -- 即与@JsonIgnore
相同 -- 如果您注册了Hibernate5Module
。该类位于jackson-datatype-hibernate5
中。可能还有其他数据类型库也会执行相同的操作。 - Matthew Read@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()
添加注释(记住序列化时的getter),@Transient
将会产生
{"name":"Demonte","age":37}
Person
类代码并删除@Transient
,将transient
添加到password
变量中,并且还要向Jackson映射程序添加一个功能以告诉它如何处理标记为transient
的字段。transient String password;
并且
mapper.configure(MapperFeature.PROPAGATE_TRANSIENT_MARKER, true);
(请记住,Jackson在序列化时使用getter而不是直接使用成员变量)然后您将获得相同的输出。
@Transient
字段不会被 Jackson 进行序列化/反序列化? - Erik Gillespie