首页 文章

Jackson :如何防止现场序列化

提问于
浏览
128

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

class User {
    private String password;

    //setter, getter..
}

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

我如何与 Jackson 完成这项任务?

9 回答

  • 7

    您可以将其标记为 @JsonIgnore .

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

  • 31

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

    private String password;
    
    @JsonIgnore
    public String getPassword() {
        return password;
    }
    
    @JsonProperty
    public void setPassword(String password) {
        this.password = password;
    }
    
  • 151

    简单的方法是注释你的getter和setter .

    以下是修改后的原始示例以排除纯文本密码,但随后注释一个只将密码字段作为加密文本返回的新方法 .

    class User {
        private String password;
    
        public void setPassword(String password){...}
        @JsonIgnore
        public String getPassword(){...}
    
        @JsonProperty("password"}
        public String getEncryptedPassword(){...}
    }
    
  • 0

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

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

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

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

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

  • 16

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

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

    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
    
  • 0

    将变量设为

    @JsonIgnore

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

相关问题