java - jsoninclude - Solo se usa @JsonIgnore durante la serialización, pero no la deserialización
jsonignoreproperties allowgetters (5)
Tengo un objeto de usuario que se envía desde y hacia el servidor. Cuando envío el objeto de usuario, no deseo enviar la contraseña con hash al cliente. Así que agregué @JsonIgnore
en la propiedad de la contraseña, pero esto también impide que se deserialice en la contraseña, lo que dificulta el @JsonIgnore
de usuarios cuando no tienen una contraseña.
¿Cómo puedo hacer que @JsonIgnore
aplique a la serialización y no a la deserialización? Estoy usando Spring JSONView por lo que no tengo un montón de control sobre el ObjectMapper
.
Cosas que he probado:
- Añadir
@JsonIgnore
a la propiedad - Agregar
@JsonIgnore
en el método getter
Desde la versión 2.6: una forma más intuitiva es usar la anotación com.fasterxml.jackson.annotation.JsonProperty
en el campo:
@JsonProperty(access = Access.WRITE_ONLY)
private String myField;
Incluso si existe un captador, el valor del campo se excluye de la serialización.
JavaDoc dice:
/**
* 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
En caso de que lo necesite al revés, simplemente use Access.READ_ONLY
.
En mi caso, tengo que Jackson serializa / deserializa automáticamente los objetos que devuelvo de un controlador Spring MVC (estoy usando @RestController con Spring 4.1.6). Tuve que usar com.fasterxml.jackson.annotation.JsonIgnore
lugar de org.codehaus.jackson.annotate.JsonIgnore
, de lo contrario simplemente no hizo nada.
Exactamente cómo hacer esto depende de la versión de Jackson que estés usando. Esto cambió alrededor de la versión 1.9 , antes de eso, puedes hacer esto agregando @JsonIgnore
al getter.
Lo que has probado:
Agregar @JsonIgnore solo en el método getter
Haga esto y también agregue una anotación específica @JsonProperty
para el nombre de campo "contraseña" de JSON al método de establecimiento de la contraseña en su objeto.
Las versiones más recientes de Jackson han agregado los argumentos de anotación READ_ONLY
y WRITE_ONLY
para JsonProperty
. Entonces también podrías hacer algo como:
@JsonProperty(access = Access.WRITE_ONLY)
private String password;
Los documentos se pueden encontrar here .
Para lograr esto, todo lo que necesitamos son dos anotaciones:
-
@JsonIgnore
-
@JsonProperty
Use @JsonIgnore
en el miembro de la clase y su captador. Use @JsonProperty
en su setter.
Una ilustración de ejemplo ayudaría a hacer esto:
class User{
// More fields here
@JsonIgnore
private String password;
@JsonIgnore
public String getPassword() {
return password;
}
@JsonProperty
public void setPassword(String password) {
this.password = password;
}
}
"user": {
"firstName": "Musa",
"lastName": "Aliyev",
"email": "[email protected]",
"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
}