Джексон: как предотвратить сериализацию поля

У меня есть класс сущности с полем пароля:

class User {
    private String password;

    //setter, getter..
}

Я хочу, чтобы это поле было пропущено во время сериализации. Но он все равно должен был бы DEserialize. Это необходимо, так что клиент может отправить мне новый пароль, но не сможет прочитать текущий.

Как это сделать с Джексоном?

Ответ 1

Вы можете пометить его как @JsonIgnore.

В @JsonIgnore 1.9 вы можете добавить @JsonIgnore для getter, @JsonProperty для setter, чтобы десериализовать, но не сериализовать.

Ответ 2

Иллюстрируя сказанное StaxMan, это работает для меня

private String password;

@JsonIgnore
public String getPassword() {
    return password;
}

@JsonProperty
public void setPassword(String password) {
    this.password = password;
}

Ответ 3

Самый простой способ - комментировать ваши методы получения и установки.

Вот оригинальный пример, измененный, чтобы исключить простой текстовый пароль, но затем аннотировать новый метод, который просто возвращает поле пароля в виде зашифрованного текста.

class User {

    private String password;

    public void setPassword(String password) {
        this.password = password;
    }

    @JsonIgnore
    public String getPassword() {
        return password;
    }

    @JsonProperty("password")
    public String getEncryptedPassword() {
        // encryption logic
    }
}

Ответ 4

Помимо @JsonIgnore, существует еще пара возможностей:

  • Используйте JSON Views, чтобы отфильтровать поля условно (по умолчанию, не используется для десериализации, в 2.0 будет доступно, но вы можете использовать другое представление по сериализации, десериализации)
  • @JsonIgnoreProperties в классе может быть полезно

Ответ 5

Начиная с Jackson 2.6, свойство может быть помечено как read- или только для записи. Это проще, чем взламывать аннотации на обоих средствах доступа и хранить всю информацию в одном месте:

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

Ответ 6

transient - решение для меня. благодарю! он является родным для Java и позволяет вам добавлять еще одну аннотацию, связанную с каркасом.

Ответ 7

Нужно спросить, почему вам нужен публичный метод получения пароля. Спящий режим или любая другая структура ORM будет работать с частным методом получения. Для проверки правильности пароля вы можете использовать

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

Ответ 8

Джексон имеет класс с именем 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

Ответ 9

установить переменную как

@JsonIgnore

Это позволяет переменной быть пропущенным сериализатором json