Сериализация Джексона, выводящая две строки json для одной переменной java

У меня странная проблема при переносе кода с Java 8 и Sprint Boot 1.X на 11 и 2.X. Ранее я обнаружил, что Джексон сериализует private boolean isAvailable как в available: false, так и в isAvailable: false. Чтобы добавить больше путаницы, Ломбок идет с нами, поэтому я не могу видеть, что происходит с получателем, и если это вызывает конфликт. Ниже приведен код класса Java:

@Data
public class Availability{

    @JsonProperty("isAvailable")
    private boolean isAvailable;

}

И восстановленный JSON из картографа объектов Джексона был:

"Availability" : [{
          "isAvailable" : false,
          "available" : false }]

Это было с Джексоном 2,8. Теперь с Jackson 2.10 я получаю только isAvailable: false как результат в JSON от ObjectMapper.

"Availability" : [{
          "isAvailable" : false }]

Мне кажется логичным, что оно должно соответствовать только имени переменной Java, но, к сожалению, в контракте есть обе версии, и я не хочу менять контракт. Некоторые используют это, а некоторые нет. Я знаю, что настраиваемый сериализатор возможен, но не знаю, как это сделать и если это необходимо.


person Barton Durbin    schedule 14.08.2020    source источник


Ответы (1)


Это ломбок + поле, взаимодействующее.

Давайте возьмем этот гипотетический класс (здесь нет ломбока или, если на то пошло, Джексона вообще):

class Example {
    public boolean isAvailable() {
        return true;
    }
}

Согласно beanspec, класс Example имеет единственное свойство bean-компонента только для чтения типа boolean, называемое available. Это потому, что любой метод без аргументов, который возвращает логическое значение и начинается с is (а затем с заглавной буквы), считается средством доступа, и чтобы добраться до его имени, удалите is.

Так что смотрим на это с той стороны. Теперь давайте посмотрим на это с другой стороны, вы пишете класс, в котором по какой-то причине вы решили, что поле должно называться isAvailable. Реальный вопрос: как вы хотите, чтобы «свойство» было названо (согласно beanspec)? Если он действительно должен называться isAvailable, есть только один способ добиться этого:

class Example {
    public boolean isIsAvailable() {
        return true;
    }
}

Да, isIsAvailable. Выглядит глупо, но это то, что предписывают правила, если вы хотите, чтобы само свойство называлось isAvailable. Ломбок решил (ИСТОЧНИК: я основной участник), что никому не нужен метод с именем isIsAvailable, когда вы наклеиваете аннотацию @Getter на поле с именем isAvailable.

Итак, теперь у вас есть класс, который с точки зрения Джексона выглядит примерно так:

class Availability {
    @JsonProperty("isAvailable") private boolean isAvailable;

    public boolean isAvailable() { return this.isAvailable; }
}

Не используя особого интеллекта, просто применяя буквальные правила, Джексон говорит: Хорошо, здесь есть 2 различных свойства, available (получено путем вызова isAvailable()) и поле isAvailable. Для геттеров в стиле beanspec _18 _ / _ 19_ удаляется, для полей - нет, особенно если вы вставляете туда @JsonProperty("isAvailable").

Это контекст, почему все это происходит.

Решением может быть использование этого метода:

@JsonProperty("available")
public boolean getAvailable() { return this.available; }

Я думаю, что это даст вам оба варианта в вашем выводе JSON.

person rzwitserloot    schedule 14.08.2020
comment
Я ценю ваши комментарии. Работа с устаревшим кодом - это определенно неприятность, и я понимаю спецификацию Java bean-компонентов и то, как Джексон и Ломбок должны с этим справляться. Я немного озадачен, почему поведение изменилось, когда зависимости изменились, а лежащий в основе pojo не был изменен. - person Barton Durbin; 15.08.2020
comment
Я бы сказал, что обычно получать как «доступно», так и «isAvailable» нежелательно, поэтому, по-видимому, Джексон, обновленный до того же интеллектуального ломбока, применяется. Мы в lombok несколько раз нарушали обратную совместимость в таких экзотических случаях, не придавая особого значения этому (не v2.0 или еще много чего), может быть, они тоже? - person rzwitserloot; 15.08.2020
comment
Я скажу вам, что такой способ написания геттера со свойством json, безусловно, сработал, но пора поговорить с клиентами и изменить контракт. Отстой, почему раньше этого никто не замечал. Я ненавижу наследовать код, но такая жизнь иногда бывает в мире программного обеспечения! Еще раз спасибо, и, кстати, Ломбок - шаблонный спасатель. - person Barton Durbin; 15.08.2020