【问题标题】:Only using @JsonIgnore during serialization, but not deserialization仅在序列化期间使用@JsonIgnore,而不是反序列化
【发布时间】:2012-09-12 09:03:47
【问题描述】:

我有一个发送到服务器和从服务器发送的用户对象。当我发送用户对象时,我不想将散列密码发送给客户端。所以,我在密码属性上添加了@JsonIgnore,但这也阻止了它被反序列化为密码,这使得没有密码的用户很难注册。

我怎样才能只让@JsonIgnore 应用于序列化而不是反序列化?我正在使用 Spring JSONView,所以我无法控制 ObjectMapper

我尝试过的事情:

  1. 在属性中添加@JsonIgnore
  2. 仅在 getter 方法上添加 @JsonIgnore

【问题讨论】:

    标签: java json spring annotations jackson


    【解决方案1】:

    具体如何执行此操作取决于您使用的 Jackson 版本。这在 1.9 版本周围发生了变化,在此之前,您可以通过将 @JsonIgnore 添加到 getter 来做到这一点。

    你尝试过的:

    仅在 getter 方法上添加 @JsonIgnore

    执行此操作,为您的 JSON“密码”字段名称添加一个特定的 @JsonProperty 注释到对象密码的 setter 方法。

    Jackson 的最新版本为JsonProperty 添加了READ_ONLYWRITE_ONLY 注释参数。所以你也可以这样做:

    @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
    private String password;
    

    文档可以在here找到。

    【讨论】:

    • gist.github.com/thurloat/2510887 for Jackson JSON 仅在 反序列化 上忽略
    • AFAIK 你仍然必须实现设置器并对其进行注释。我只想要序列化的吸气剂。你说的瞬态是什么?这是一个 JPA 注释 AFAIK
    • 另外,请确保从字段本身中删除 @JsonProperty 否则它将覆盖您的 getter/setter 注释
    • @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
    • Jackson-annotations 2.5 没有后面的功能。 Jackson-annotations 2.6.3 确实
    【解决方案2】:

    为了做到这一点,我们只需要两个注解:

    1. @JsonIgnore
    2. @JsonProperty

    在类成员及其 getter 上使用 @JsonIgnore,在其 setter 上使用 @JsonProperty。示例插图将有助于做到这一点:

    class User {
    
        // More fields here
        @JsonIgnore
        private String password;
    
        @JsonIgnore
        public String getPassword() {
            return password;
        }
    
        @JsonProperty
        public void setPassword(final String password) {
            this.password = password;
        }
    }
    

    【讨论】:

    • 这是杰克逊 2.6.4 唯一对我有用的东西。我尽力使用 @JsonProperty(access = Access.WRITE_ONLY) 但它对我不起作用。
    【解决方案3】:

    从2.6版开始:更直观的方式是在字段上使用com.fasterxml.jackson.annotation.JsonProperty注解:

    @JsonProperty(access = Access.WRITE_ONLY)
    private String myField;
    

    即使存在 getter,字段值也会从序列化中排除。

    JavaDoc 说:

    /**
     * Access setting that means that the property may only be written (set)
     * for deserialization,
     * but will not be read (get) on serialization, that is, the value of the property
     * is not included in serialization.
     */
    WRITE_ONLY
    

    如果您需要它,只需使用Access.READ_ONLY

    【讨论】:

    • 我不明白为什么赞成票这么少,这是解决这个问题的优雅方法,就像一个魅力。无需注释 getter、setter 和 field。唯一的领域。谢谢。
    • 可能是 2.6+ 用户的最佳答案。
    • 确保您没有使用 org.codehaus.jackson.annotate 导入。 @DanielBeer 的解决方案适用于 Jackson 2.6.3。既然杰克逊已经更新,这应该是公认的答案。
    【解决方案4】:

    就我而言,我让 Jackson 自动(反)序列化从 Spring MVC 控制器返回的对象(我在 Spring 4.1.6 中使用 @RestController)。我必须使用com.fasterxml.jackson.annotation.JsonIgnore 而不是org.codehaus.jackson.annotate.JsonIgnore,否则,它根本什么也没做。

    【讨论】:

    • 这是一个非常有用的答案,它确实帮助我找到了杰克逊不尊重 @JsonIgnore 的原因......谢谢!
    【解决方案5】:

    另一种简单的处理方法是在注解中使用参数allowSetters=true。这将允许将密码反序列化到您的 dto 中,但不会将其序列化为使用包含对象的响应正文。

    示例:

    @JsonIgnoreProperties(allowSetters = true, value = {"bar"})
    class Pojo{
        String foo;
        String bar;
    }
    

    foobar 都填充在对象中,但只有 foo 写入响应正文。

    【讨论】:

    • 那是我的错误,我没有意识到你已经更正了sn-p。查看您的更改,看来我多年来在 Groovy 中的写作让我受益匪浅,而我对 Java 的翻译有点粗糙。对不起!
    【解决方案6】:
    "user": {
            "firstName": "Musa",
            "lastName": "Aliyev",
            "email": "klaudi2012@gmail.com",
            "passwordIn": "98989898", (or encoded version in front if we not using https)
            "country": "Azeribaijan",
            "phone": "+994707702747"
        }
    

    @CrossOrigin(methods=RequestMethod.POST)
    @RequestMapping("/public/register")
    public @ResponseBody MsgKit registerNewUsert(@RequestBody User u){
    
            root.registerUser(u);
    
        return new MsgKit("registered");
    }  
    

    @Service
    @Transactional
    public class RootBsn {
    
        @Autowired UserRepository userRepo;
    
        public void registerUser(User u) throws Exception{
    
            u.setPassword(u.getPasswordIn());
            //Generate some salt and  setPassword (encoded -  salt+password)
            User u=userRepo.save(u);
    
            System.out.println("Registration information saved");
        }
    
    }
    

        @Entity        
    @JsonIgnoreProperties({"recordDate","modificationDate","status","createdBy","modifiedBy","salt","password"})
                        public class User implements Serializable {
                            private static final long serialVersionUID = 1L;
    
                            @Id
                            @GeneratedValue(strategy=GenerationType.AUTO)
                            private Long id;
    
                            private String country;
    
                            @Column(name="CREATED_BY")
                            private String createdBy;
    
                            private String email;
    
                            @Column(name="FIRST_NAME")
                            private String firstName;
    
                            @Column(name="LAST_LOGIN_DATE")
                            private Timestamp lastLoginDate;
    
                            @Column(name="LAST_NAME")
                            private String lastName;
    
                            @Column(name="MODIFICATION_DATE")
                            private Timestamp modificationDate;
    
                            @Column(name="MODIFIED_BY")
                            private String modifiedBy;
    
                            private String password;
    
                            @Transient
                            private String passwordIn;
    
                            private String phone;
    
                            @Column(name="RECORD_DATE")
                            private Timestamp recordDate;
    
                            private String salt;
    
                            private String status;
    
                            @Column(name="USER_STATUS")
                            private String userStatus;
    
                            public User() {
                            }
                    // getters and setters
                    }
    

    【讨论】:

    • 在未来对代码的工作原理进行简要描述可能会有所帮助。
    • 好吧!!你在这里尝试什么?获得更多选票?大声笑
    【解决方案7】:

    您可以在类级别使用@JsonIgnoreProperties,并将您想要在json中设置的变量放在“值”参数中。对我来说很好。

    @JsonIgnoreProperties(value = { "myVariable1","myVariable2" })
    public class MyClass {
          private int myVariable1;,
          private int myVariable2;
    }
    

    【讨论】:

      【解决方案8】:

      你也可以这样做:

      @JsonIgnore
      @JsonProperty(access = Access.WRITE_ONLY)
      private String password;
      

      对我有用

      【讨论】:

      • 它将完全忽略。这不是所问的。 JsonIgnore 优先于 JsonProperty。
      猜你喜欢
      • 2019-09-21
      • 2015-09-24
      • 2011-10-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多