仅在序列化期间使用@JsonIgnore,但不反序列化

时间:2012-09-20 01:49:35

标签: java json spring annotations jackson

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

如何才能将@JsonIgnore应用于序列化而不是反序列化?我正在使用Spring JSONView,因此我无法控制ObjectMapper

我尝试过的事情:

  1. @JsonIgnore添加到媒体资源
  2. 仅在getter方法上添加@JsonIgnore

8 个答案:

答案 0 :(得分:392)

具体如何做到这一点取决于你正在使用的杰克逊版本。这改变了版本 1.9 ,在此之前,您可以通过将@JsonIgnore添加到getter来实现此目的。

您尝试过:

  

仅在getter方法上添加@JsonIgnore

执行此操作,以及将JSON“密码”字段名称的特定@JsonProperty注释添加到对象密码的setter方法中。

杰克逊的更新版本为READ_ONLY添加了WRITE_ONLYJsonProperty注释参数。所以你也可以这样做:

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

可以找到文档here

答案 1 :(得分:89)

为了实现这一目标,我们需要的只是两个注释:

  1. @JsonIgnore
  2. @JsonProperty
  3. 在类成员及其getter上使用@JsonIgnore。 在其设置器上使用@JsonProperty

    示例说明有助于实现此目的:

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

答案 2 :(得分:66)

从版本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

答案 3 :(得分:10)

在我的情况下,我让Jackson自动序列化/反序列化我从Spring MVC控制器返回的对象(我在Spring 4.1.6中使用@RestController)。我不得不使用com.fasterxml.jackson.annotation.JsonIgnore代替org.codehaus.jackson.annotate.JsonIgnore,否则它什么也没做。

答案 4 :(得分:2)

"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
                }

答案 5 :(得分:0)

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

示例:

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

foobar都填充在对象中,但是只有foo被写入响应主体。

答案 6 :(得分:0)

您可以在类级别使用@JsonIgnoreProperties,然后将要igonre的变量放在json中的“值”参数中。对我有用。

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

答案 7 :(得分:0)

您也可以这样做:

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

对我有用