使用静态方法为具有给定超类的类型配置 Jackson Deserialzer

问题描述 投票:0回答:1

目前,我在反序列化代码表类型类时遇到异常。

想象以下场景:

public abstract class AbstractCodestableEntry implements java.io.Serializable {

    private final String category;
    private final String code;

    protected AbstractCodestableEntry(final String category, final String code) {
        this.category = category;
        this.code = code;
    }

    // Getter for category and code
}

这是具体代码表类的一个示例。这种类型我们有大约 100 个类(称呼、性别、工作日……以及更多功能相关的代码表)

public class SalutationCodestableEntry extends AbstractCodestableEntry {

    public static final String KATEGORIE = "SALUTATION";

    public static final SalutationCodestableEntry MR = new SalutationCodestableEntry ("1");
    public static final SalutationCodestableEntry MRS = new SalutationCodestableEntry ("2");
    ...

    private static final Map<String, SalutationCodestableEntry> BY_CODE = initCache();

    private SalutationCodestableEntry(final String code) {
        super(KATEGORIE, code);
    }

    private static Map<String, SalutationCodestableEntry> initCache() {
        final SalutationCodestableEntry[] values = new SalutationCodestableEntry[] {MR, MRS, ...};
        final Map<String, SalutationCodestableEntry> map = new HashMap<>();
        for (final SalutationCodestableEntry e : values) {
            map.put(e.getCode(), e);
        }
        return Collections.unmodifiableMap(map);
    }

    public static SalutationCodestableEntry valueOf(final String code) {
        return BY_CODE.get(code);
    }
}

将 SalutationCodestableEntry 类型的属性序列化为 JSON 时,它看起来像这样

"org.company.SalutationCodestableEntry":{"category":"SALUTATION","code":"1"}

当前反序列化时出现以下异常:

com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `org.company.SalutationCodestableEntry` (although at least one Creator exists): cannot deserialize from Object value (no delegate- or property-based Creator)
at [Source: UNKNOWN; byte offset: #UNKNOWN] (through reference chain: java.lang.Object[][0]->org.company.Dto["codestableEntry"])

我可以随心所欲地调整所有课程,但实际上

  • 我不想将构造函数公开(因为开发人员不应该能够创建一个新的 SalutationCodestableEntry,其值 -99 没有任何功能意义)。
  • 我不想调整我所有具体的〜100个代码表类
  • 我不想在类中添加任何 Jackson 注释。我更喜欢单独配置解串器的映射。但如果在抽象超类中有一个带有注释的简单解决方案,我会同意这一点。

我已经使用 Mixins 为一些类做了一些特殊的序列化配置。但这似乎在这里不起作用,因为继承(SalutationCodestableEntry 扩展了 AbstractCodestableEntry)和使用静态方法返回对象(

SalutationCodestableEntry.valueOf(String code)
)。

目前我的 ObjectMapper 配置如下所示

    @Bean(name = OBJECTMAPPER_QUALIFIER)
    public ObjectMapper outboxObjectMapper() {    
        return new ObjectMapper()
            .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true)
            .registerModule(new JavaTimeModule())
            .addMixIn(AnySpecialClass.class, AnySpecialClassMixin.class)
            .addMixIn(...);
    }

有什么方法可以让 Jackson 知道如何反序列化 codetable 类(如 SalutationCodestableEntry)吗?

jackson json-deserialization jackson-databind
1个回答
0
投票

我在 Jackson 的 GitHub 上问了这个问题:https://github.com/FasterXML/jackson/discussions/237

我通过向所有具体的代码表类添加 @JsonCreator 注释来解决这个问题,例如

    @JsonCreator
    public static SalutationCodestableEntry valueOf(final @JsonProperty("code") code) {
        return BY_CODE.get(code);
    }

随着代码表类的生成,我能够调整生成器,在这种情况下,这对我来说似乎是最简单的解决方案,即使我正在寻找另一个集中式解决方案而不修改具体的代码表类。

© www.soinside.com 2019 - 2024. All rights reserved.