Jackson: cómo prevenir la serialización de campo

Tengo una clase de entidad con un campo de contraseña:

class User { private String password; //setter, getter.. } 

Quiero que este campo se omita durante la serialización. Pero todavía debería poder DESESALIZARSE. Esto es necesario, para que el cliente pueda enviarme una nueva contraseña, pero no pueda leer la actual.

¿Cómo logro esto con Jackson?

Puede marcarlo como @JsonIgnore .

Con 1.9, puede agregar @JsonIgnore para getter, @JsonProperty para setter, para deserializar pero no serializar.

Ilustrando lo que StaxMan ha declarado, esto funciona para mí

 private String password; @JsonIgnore public String getPassword() { return password; } @JsonProperty public void setPassword(String password) { this.password = password; } 

La manera más fácil es anotar sus getters y setters.

Aquí está el ejemplo original modificado para excluir la contraseña de texto sin formato, pero luego anote un nuevo método que simplemente devuelve el campo de contraseña como texto encriptado.

 class User { private String password; public void setPassword(String password){...} @JsonIgnore public String getPassword(){...} @JsonProperty("password"} public String getEncryptedPassword(){...} } 

Además de @JsonIgnore , hay un par de otras posibilidades:

  • Utilice Vistas JSON para filtrar campos condicionalmente (de manera predeterminada, no se utiliza para la deserialización; en 2.0 estará disponible, pero puede usar una vista diferente en la serialización, la deserialización)
  • @JsonIgnoreProperties en la clase puede ser útil

transient es la solución para mí. ¡Gracias! es nativo de Java y le evita agregar otra anotación específica del marco.

A partir de Jackson 2.6 , una propiedad se puede marcar como de solo lectura o escritura. Es más simple que piratear las anotaciones en ambos accesadores y mantiene toda la información en un solo lugar:

 public class User { @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) private String password; } 

Uno debería preguntarse por qué querría un método public getter para la contraseña. Hibernate, o cualquier otro marco ORM, lo hará con un método getter privado. Para verificar si la contraseña es correcta, puede usar

 public boolean checkPassword(String password){ return this.password.equals(anyHashingMethod(password)); } 

Jackson tiene una clase llamada SimpleBeanPropertyFilter que ayuda a filtrar los campos durante la serialización y la deserialización; no globalmente Creo que eso es lo que querías.

 @JsonFilter("custom_serializer") class User { private String password; //setter, getter.. } 

Luego en tu código:

 String[] fieldsToSkip = new String[] { "password" }; ObjectMapper mapper = new ObjectMapper(); final SimpleFilterProvider filter = new SimpleFilterProvider(); filter.addFilter("custom_serializer", SimpleBeanPropertyFilter.serializeAllExcept(fieldsToSkip)); mapper.setFilters(filter); String jsonStr = mapper.writeValueAsString(currentUser); 

Esto evitará que el campo de password se serialice. También podrá deserializar los campos de password tal como están. Solo asegúrese de que no se apliquen filtros en el objeto ObjectMapper.

 ObjectMapper mapper = new ObjectMapper(); User user = mapper.readValue(yourJsonStr, User.class); // user object does have non-null password field