Джексон: как предотвратить полевую сериализацию
У меня есть класс сущности с полем пароля:
class User {
private String password;
//setter, getter..
}
Я хочу, чтобы это поле было пропущено во время сериализации. Но он все еще должен быть в состоянии DEserialize. Это необходимо, чтобы клиент мог отправить мне новый пароль, но не смог прочитать текущий.
Как мне сделать это с Джексоном?
9 ответов
Вы можете пометить его как @JsonIgnore
,
С 1.9 вы можете добавить @JsonIgnore
для добытчика, @JsonProperty
для сеттера, чтобы сделать его десериализованным, но не сериализованным.
Иллюстрируя сказанное StaxMan, это работает для меня
private String password;
@JsonIgnore
public String getPassword() {
return password;
}
@JsonProperty
public void setPassword(String password) {
this.password = password;
}
Начиная с Jackson 2.6, свойство может быть помечено как доступное только для чтения или записи. Это проще, чем взломать аннотации на обоих средствах доступа и хранить всю информацию в одном месте:
public class User {
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
private String password;
}
Самый простой способ - комментировать ваши методы получения и установки.
Вот оригинальный пример, измененный, чтобы исключить простой текстовый пароль, но затем аннотировать новый метод, который просто возвращает поле пароля в виде зашифрованного текста.
class User {
private String password;
public void setPassword(String password){...}
@JsonIgnore
public String getPassword(){...}
@JsonProperty("password"}
public String getEncryptedPassword(){...}
}
Помимо @JsonIgnore
Есть несколько других возможностей:
- Используйте JSON Views для условной фильтрации полей (по умолчанию не используется для десериализации; в 2.0 будет доступно, но вы можете использовать другое представление для сериализации, десериализации)
@JsonIgnoreProperties
на уроке может быть полезно
transient
это решение для меня. Спасибо! он является родным для Java и не требует добавления другой аннотации, специфичной для фреймворка.
Джексон имеет класс с именем SimpleBeanPropertyFilter, который помогает фильтровать поля во время сериализации и десериализации; не глобально. Я думаю, это то, что вы хотели.
@JsonFilter("custom_serializer")
class User {
private String password;
//setter, getter..
}
Тогда в вашем коде:
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);
Это предотвратит password
поле для сериализации. Также вы сможете десериализовать password
поля как есть. Просто убедитесь, что фильтры не применяются к объекту ObjectMapper.
ObjectMapper mapper = new ObjectMapper();
User user = mapper.readValue(yourJsonStr, User.class); // user object does have non-null password field
Следует спросить, зачем вам нужен публичный метод получения пароля. Hibernate, или любая другая платформа ORM, будет делать с частным методом получения. Для проверки правильности пароля вы можете использовать
public boolean checkPassword(String password){
return this.password.equals(anyHashingMethod(password));
}
Установить переменную как
@JsonIgnore
Это позволяет переменной быть пропущенным сериализатором json