JSON Jackson,如何使用只读属性别名来实现向后兼容性?

时间:2016-05-04 14:30:41

标签: java json jackson

我们有一个代表某种配置的结构。我们在周期性这个词中有一个拼写错误,它被错误拼写为' o' as period * o * city 。下面的示例源是更正的源。但是,我需要能够读取旧的配置文件以保持向后兼容性。

我可以让JSON Jackson在反序列化时识别拼写错误的字段/属性但在序列化时忽略它吗?

我们正在使用JSON Jackson的2.6.6版本。

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

1 个答案:

答案 0 :(得分: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中的额外字段,你可以添加这样的setter:

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);

Btw在Gson中只需1行即可完成@SerializedName(value="name", alternate={"name2"}) public String name = null;