Джексон: як запобігти серіалізації поля


163

У мене є клас сутності з полем пароля:

class User {
    private String password;

    //setter, getter..
}

Я хочу, щоб це поле було пропущено під час серіалізації. Але це все ж має бути в змозі десеріалізувати. Це потрібно, щоб клієнт міг надіслати мені новий пароль, але не зміг прочитати поточний.

Як мені це зробити з Джексоном?


1
Ви не хочете його серіалізувати, але ви хочете мати можливість його десаріалізувати? Це неможливо, я б сказав. Якщо ви не покладете файл cookie у вікно, ви не зможете отримати його з цього поля.
Олексій Дуфрой

1
@Traroth: але я можу поставити НОВЕ cookie. Я просто шукаю зручну анотацію, але це, безумовно, можна зробити вручну.
тиждень

8
Швидкий коментар: технічно цілком можливо мати сеттер, який використовується (навіть приватні автоматично виявляються) та просто опустити аксесуар (немає публічного поля чи геттера). Можна також додавати @JsonIgnoreна getter, але @JsonPropertyна setter, і в цьому випадку речі не серіалізуються, але можуть бути десеріалізовані.
StaxMan

4
Чи не проти прийняти відповідь на це запитання? (Парі вашим іншим кілька років і досі теж неприйнято ... Будь ласка, розгляньте перегляд!) :) Повне розкриття інформації - у мене немає відповідей на жодне з цих питань.
Баретт

Відповіді:


187

Ви можете позначити його як @JsonIgnore.

З 1.9 ви можете додати @JsonIgnoreдля getter, @JsonPropertyдля сеттера, щоб зробити його деріаріалізованим, але не серіалізувати.


6
@JsonIgnore також запобігає десеріалізації. Для тимчасових - я це перевірю.
тиждень

98
З 1.9 ви можете додати @JsonIgnoreдля getter, @JsonPropertyдля сеттера, щоб зробити його деріаріалізованим, але не серіалізувати.
StaxMan

Коментар StaxMan повинен бути відповіддю, чи не так? Чому це все-таки коментар ...! ..?
Сараванабалаги Рамачандран

схоже, що тимчасовий не працює для мене, я позначив поле "тимчасовим", що я не хочу, щоб воно було серилізовано / дезаріалізоване.
рохіт

Ця відповідь раніше пропонувала використовувати transient(як у private transient String password;), але перехідні поля з загальнодоступними дітьми ігноруються, якщо MapperFeature.PROPAGATE_TRANSIENT_MARKER не ввімкнено.
tom

96

Ілюструючи те, що заявив StaxMan, це працює для мене

private String password;

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

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

12
Яку залежність від Json ви використовуєте? Це не працює з com.fasterxml.jackson
Олександр Буракевич

3
Дякую! @JsonIgnoreНа полі не потрібно, здається.
Ферран Мейлінч

com.fasterxml.jackson.annotation.JsonIgnore from jackson-annotations- <version> .jar
mvmn

Я спробував це, і це не працює для мене. Я використовую v2.8. Будь-яка допомога?
Маз

36

Найпростіший спосіб - анотувати ваші жителі та сетери.

Ось оригінальний приклад, модифікований для виключення простого текстового пароля, але потім анотувати новий метод, який просто повертає поле пароля як зашифрований текст.

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
    }
}

21

Починаючи з Jackson 2.6 , властивість може бути позначена як лише для читання або для запису. Це простіше, ніж зламати примітки на обох аксесуарах і зберігати всю інформацію в одному місці:

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

Це дивовижне рішення, просте, робоче. Дякую.
dhqvinh

17

Крім цього @JsonIgnore, є ще кілька інших можливостей:

  • Використовуйте представлення JSON для умовного фільтрування полів (за замовчуванням не використовується для десеріалізації; в 2.0 буде доступно, але ви можете використовувати інший погляд на серіалізацію, десеріалізацію)
  • @JsonIgnoreProperties на уроці може бути корисним

10

transientце рішення для мене. Дякую! він є рідним для Java і уникає додавання ще однієї рамкової анотації.


2
Це працює, якщо ваш атрибут справді короткочасний, не задіяний ORM, наприклад .... Знайдений @JsonIgnore є більш цікавим у моєму випадку, хоч би я був заблокований до Джексона, але це вдалий компроміс
Жоао Перейра

3
Вам не доведеться замикатися на Джексона, якщо ви створюєте свою власну анотацію та її коментують JsonIgnore та JacksonAnnotationsInside. Таким чином, якщо ви змінюєте серіалізатори, вам залишається лише змінити власне анотацію.
DavidA

4

Слід запитати, чому ви хочете отримати загальнодоступний метод отримання пароля. Зимова сплячка або будь-яка інша рамка ORM робитиме приватний метод отримання. Щоб перевірити правильність пароля, ви можете використовувати

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

Я насправді думаю, що це найкращий спосіб подумати над рішенням. Більше сенсу робити речі, які вам потрібні приватними, і контролювати їх від самого об’єкта.
arcynum

2

Джексон має клас під назвою 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

0

встановити змінну як

@JsonIgnore

Це дозволяє пропустити змінну серіалізатором json

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.