@JsonIgnore vs @Transient - 区别?

@JsonIgnore vs @Transient -difference?

用于序列化和反序列化的跳过字段。

@JsonIgnore 如果@Transient 也跳过序列化和反序列化过程中的字段,为什么我们应该使用它?

两者之间的明显区别在于,@Transient 用作 JPA 的一部分,以忽略标记为 @Transient 的字段。

其中 @JsonIgnore 仅用于忽略标记字段的序列化、反序列化和 JSON。

这意味着标记为 @JsonIgnore 的字段仍然可以在 JPA 持久性中持久化,而标记为 @Transient 的字段既不会被持久化也不会被序列化、反序列化。

我们应该区分javax.persistence.Transient and java.beans.Transient. As mentioned by @shazin and @Abhishek Kumar, the former signals JPA to ignore the property for persistence and does not affect marshalling. Jackson treats the latter the same as JsonIgnore during marshalling, as can be seen in 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

@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() (记住序列化的getters) @Transient会产生

{"name":"Demonte","age":37}

现在,如果您重新访问 Person class 代码并删除 @Transient 并将 transient 添加到 password 变量,并向Jackson 映射器告诉它如何处理标记为 transient

的字段
transient String password;

mapper.configure(MapperFeature.PROPAGATE_TRANSIENT_MARKER, true);

(记住 Jackson 使用 getter 而不是成员直接进行序列化) 那么你会得到相同的输出。