我有一个发送到服务器和从服务器发送的用户对象。当我发送用户对象时,我不想将散列密码发送给客户端。因此,我在密码属性上添加了 @JsonIgnore
,但这也阻止了它被反序列化为密码,这使得在没有密码时很难注册用户。
我怎样才能让 @JsonIgnore
应用于序列化而不是反序列化?我正在使用 Spring JSONView,因此我无法控制 ObjectMapper
。
我尝试过的事情:
将@JsonIgnore 添加到属性中 仅在getter 方法上添加@JsonIgnore
具体如何执行此操作取决于您使用的 Jackson 版本。这在 1.9 版本周围发生了变化,在此之前,您可以通过将 @JsonIgnore
添加到 getter 来实现。
您尝试过的:
仅在 getter 方法上添加 @JsonIgnore
执行此操作,还将您的 JSON“密码”字段名称的特定 @JsonProperty
注释添加到对象密码的 setter 方法。
更新的 Jackson 版本为 JsonProperty
添加了 READ_ONLY
和 WRITE_ONLY
注释参数。因此,您还可以执行以下操作:
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
private String password;
可以在 here 中找到文档。
为了做到这一点,我们只需要两个注解:
@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;
}
}
从 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
。
在我的例子中,我让 Jackson 自动(反)序列化从 Spring MVC 控制器返回的对象(我在 Spring 4.1.6 中使用 @RestController)。我必须使用 com.fasterxml.jackson.annotation.JsonIgnore
而不是 org.codehaus.jackson.annotate.JsonIgnore
,否则,它根本什么也没做。
处理此问题的另一种简单方法是在注释中使用参数 allowSetters=true
。这将允许将密码反序列化到您的 dto 中,但不会将其序列化为使用包含对象的响应正文。
例子:
@JsonIgnoreProperties(allowSetters = true, value = {"bar"})
class Pojo{
String foo;
String bar;
}
foo
和 bar
都填充在对象中,但只有 foo 写入响应正文。
"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
}
您可以在类级别使用 @JsonIgnoreProperties 并将您想要在 json 中的变量放入“值”参数中。对我来说很好。
@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;
}
}
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)