JSON Джексон, как использовать псевдоним свойства только для чтения для обратной совместимости?

У нас есть структура, которая представляет некоторую конфигурацию. У нас была опечатка в слове периодичность, оно было неправильно написано с буквой "о" как период*о*город. Ниже пример исходного кода является исправленным. Однако мне нужно иметь возможность читать старые файлы конфигурации для обеспечения обратной совместимости.

Можно ли заставить JSON Jackson распознавать поле/свойство с ошибкой при десериализации, но игнорировать его при сериализации?

Мы используем версию 2.6.6 JSON Jackson.

package foo;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;

@JsonInclude(Include.NON_EMPTY)
@JsonIgnoreProperties(ignoreUnknown = true)
public class Rule {
    private LogPeriodicity periodicityLevel;
    private Integer periodicity;

    // ctors and some other methods omitted for brevity

    public LogPeriodicity getPeriodicityLevel() {
        return periodicityLevel;
    }

    public void setPeriodicityLevel(LogPeriodicity periodicityLevel) {
        this.periodicityLevel = periodicityLevel;
    }

    public Integer getPeriodicity() {
        return periodicity;
    }

    public void setPeriodicity(Integer periodicity) {
        this.periodicity = periodicity;
    }
}

person wilx    schedule 04.05.2016    source источник


Ответы (1)


Если я правильно понял ваш вопрос, вы хотите что-то вроде этого?

MyClass obj =  mapper.readValue("{ \"name\" : \"value\"}", MyClass.class);
String serialized = mapper.writeValueAsString(obj);

MyClass obj2 =  mapper.readValue("{ \"name2\" : \"value\"}", MyClass.class);
String serialized2 = mapper.writeValueAsString(obj2);

if( Objects.equals(serialized2, serialized))
    System.out.println("Success " + serialized + " == " + serialized2 );

если вам не нужно дополнительное поле в POJO, вы можете просто добавить сеттер следующим образом:

public static class MyClass {
    @JsonProperty
    private String name = null;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @JsonSetter
    public void setName2(String name2) {
        setName(name2);
    }
}

Возможно, вы также можете зарегистрировать устаревший Mixin вместо @JsonSetter.

public abstract class  LegacyMyClassMixIn{
    @JsonProperty("name")
    private String name;
    @JsonGetter("name")
    public abstract String getName();
    @JsonSetter("name2")
    public abstract void setName(String name) ;
}

И используйте это так:

SimpleModule module = new SimpleModule();
module.setMixInAnnotation(MyClass.class, LegacyMyClassMixIn.class);
mapper2.registerModule(module);

Кстати, в Gson это можно сделать всего одной строкой @SerializedName(value="name", alternate={"name2"}) public String name = null;

person varren    schedule 04.05.2016
comment
Я использовал аннотацию @JsonSetter в установщике с ошибками, и она отлично работает для меня. Спасибо! - person wilx; 05.05.2016