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

我怎么能只得到@JsonIgnore应用于序列化而不是反序列化?我使用的是Spring JSONView,所以我对ObjectMapper没有太多的控制。

我尝试过的事情:

向属性中添加@JsonIgnore 只在getter方法上添加@JsonIgnore


具体如何做到这一点取决于您正在使用的Jackson版本。这在1.9版本左右发生了变化,在那之前,您可以通过向getter添加@JsonIgnore来做到这一点。

你已经试过了:

只在getter方法上添加@JsonIgnore

这样做,还为JSON“password”字段名添加一个特定的@JsonProperty注释,将其添加到对象上的密码setter方法。

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

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

文档可以在这里找到。


为了实现这一点,我们只需要两个注释:

@JsonIgnore @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;
    }
}

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


从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。


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

另一种简单的处理方法是在注释中使用allowSetters=true参数。这将允许密码被反序列化到dto中,但不会序列化到使用contains对象的响应体中。

例子:

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

foo和bar都被填充到对象中,但只有foo被写入响应体。


你可以在类级别使用@JsonIgnoreProperties,并将你想忽略的变量放在json的“value”参数中。对我来说还不错。

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

你还可以这样做:

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

这对我很有效


我也在找类似的东西。我仍然想序列化我的属性,但想使用不同的getter改变值。在下面的示例中,我将反序列化真实密码,但将序列化为屏蔽密码。以下是如何做到这一点:

public class User() {

    private static final String PASSWORD_MASK = "*********";

    @JsonIgnore
    private String password;

    @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
    public String setPassword(String password) {
        if (!password.equals(PASSWORD_MASK) {
            this.password = password;
        }
    }

    public String getPassword() {
        return password;
    }

    @JsonProperty("password")
    public String getPasswordMasked() {
        return PASSWORD_MASK;
    }
}

理想的解决方案是使用DTO(数据传输对象)