杰克逊:如何防止现场序列化

wee*_*ens 157 java json jackson

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

class User {
    private String password;

    //setter, getter..
}
Run Code Online (Sandbox Code Playgroud)

我希望在序列化期间跳过此字段.但它应该仍然能够反序列化.这是必需的,以便客户端可以向我发送新密码,但无法读取当前密码.

我如何与杰克逊完成这项任务?

Bij*_*men 179

您可以将其标记为@JsonIgnore.

使用1.9,您可以为setter 添加@JsonIgnoregetter @JsonProperty,以使其反序列化但不能序列化.

  • 使用1.9,你可以为getter添加`@JsonIgnore`,为setter添加`@JsonProperty`,使其反序列化但不能序列化. (95认同)
  • @JsonIgnore也可以防止反序列化.对于瞬态 - 我会检查出来. (6认同)

小智 94

说明StaxMan所说的内容,这对我有用

private String password;

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

@JsonProperty
public void setPassword(String password) {
    this.password = password;
}
Run Code Online (Sandbox Code Playgroud)

  • 你使用哪种Json依赖?这不适用于com.fasterxml.jackson (11认同)
  • 谢谢!看来,@ JsonIgnore`在球场上没有必要. (3认同)

小智 35

简单的方法是注释你的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
    }
}
Run Code Online (Sandbox Code Playgroud)


Sta*_*Man 16

除此之外@JsonIgnore,还有其他几种可能性:

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


Fra*_*eau 16

Jackson 2.6开始,可以将属性标记为只读或只写.它比攻击两个访问器上的注释更简单,并将所有信息保存在一个地方:

public class User {
    @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
    private String password;
}
Run Code Online (Sandbox Code Playgroud)


max*_*yme 10

transient对我来说是解决方案.谢谢!它是Java原生的,可以避免添加另一个特定于框架的注释.

  • 如果您创建自己的注释并且由JsonIgnore和JacksonAnnotationsInside注释,则不必锁定jackson.这样,如果更改序列化程序,则只需更改自己的注释即可. (3认同)
  • 如果你的属性真的是短暂的,而不是涉及ORM,那就行了......例如,发现@JsonIgnore在我的情况下更有趣,虽然我会被杰克逊锁定,但这是一个很好的权衡 (2认同)

krh*_*esh 5

Jackson有一个名为SimpleBeanPropertyFilter的类,帮助在序列化和反序列化过程中过滤字段;不是全球性的。我想这就是你想要的。

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

    //setter, getter..
}
Run Code Online (Sandbox Code Playgroud)

然后在你的代码中:

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);
Run Code Online (Sandbox Code Playgroud)

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

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


归档时间:

查看次数:

122306 次

最近记录:

6 年,9 月 前