Jackson: 如何防止字段序列化

我有一个带有密码字段的实体类:

class User {
private String password;


//setter, getter..
}

我希望在序列化过程中跳过此字段。但它仍然应该能够反序列化。这是必需的,以便客户端可以发送给我一个新的密码,但不能读取当前的一个。

我和杰克逊要怎么做?

156192 次浏览

你可以标记为 @JsonIgnore

在1.9中,可以为 getter 添加 @JsonIgnore,为 setter 添加 @JsonProperty,使其反序列化而不是序列化。

除了 @JsonIgnore,还有其他几种可能性:

  • 使用 JSON 视图有条件地过滤掉字段(默认情况下,不用于反序列化; 在2.0中可以使用,但是您可以使用序列化、反序列化的不同视图)
  • 课堂上的 @JsonIgnoreProperties可能有用

说明什么斯塔克斯曼说,这对我工作

private String password;


@JsonIgnore
public String getPassword() {
return password;
}


@JsonProperty
public void setPassword(String password) {
this.password = password;
}

transient是我的解决方案。谢谢! 它是 Java 原生的,避免了您添加另一个特定于框架的注释。

简单的方法是注释您的 getter 和 setter。

下面是修改后的原始示例,以排除纯文本密码,然后对一个新方法进行注释,该方法只将密码字段作为加密文本返回。

class User {


private String password;


public void setPassword(String password) {
this.password = password;
}


@JsonIgnore
public String getPassword() {
return password;
}


@JsonProperty("password")
public String getEncryptedPassword() {
// encryption logic
}
}

人们应该问为什么需要一个用于密码的公共 getter 方法。Hibernate 或任何其他 ORM 框架都可以使用私有 getter 方法。若要检查密码是否正确,可以使用

public boolean checkPassword(String password){
return this.password.equals(anyHashingMethod(password));
}

杰克逊2.6开始,属性可以标记为只读或只写。这比破解两个访问器上的注释要简单,并且可以将所有信息保存在一个地方:

public class User {
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
private String password;
}

Jackson 有一个名为 SimpleBeanPropertyFilter 的类,该类帮助在序列化和反序列化过程中筛选字段,而不是全局筛选。我想这就是你想要的。

@JsonFilter("custom_serializer")
class User {
private String password;


//setter, getter..
}

然后在你的代码中:

String[] fieldsToSkip = new String[] { "password" };


ObjectMapper mapper = new ObjectMapper();


final SimpleFilterProvider filter = new SimpleFilterProvider();
filter.addFilter("custom_serializer",
SimpleBeanPropertyFilter.serializeAllExcept(fieldsToSkip));


mapper.setFilters(filter);


String jsonStr = mapper.writeValueAsString(currentUser);

这将防止 password字段被序列化。此外,您还可以按原样反序列化 password字段。只要确保没有对 ObjectMapper 对象应用过滤器即可。

ObjectMapper mapper = new ObjectMapper();
User user = mapper.readValue(yourJsonStr, User.class);    // user object does have non-null password field

将变量设置为

@ JsonIgnore

这允许 json 序列化程序跳过变量