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

时间:2012-02-02 13:10:42

标签: java json jackson

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

class User {
    private String password;

    //setter, getter..
}

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

我如何通过杰克逊来实现这一目标?

9 个答案:

答案 0 :(得分:167)

您可以将其标记为@JsonIgnore

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

答案 1 :(得分:92)

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

private String password;

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

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

答案 2 :(得分:34)

简单的方法是注释你的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
    }
}

答案 3 :(得分:16)

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

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

答案 4 :(得分:10)

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

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

答案 5 :(得分:7)

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

答案 6 :(得分:3)

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

([regex]::Matches("DEV_ACID_C179456_2016-11-05_0009_Build",'\d{4}-\d{2}-\d{2}')).value

答案 7 :(得分:2)

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

答案 8 :(得分:0)

将变量设置为

@JsonIgnore

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