反序列化来自 JSON 请求主体的摘要 属性,基于来自该主体的另一个 属性

Deserializing abstract property from JSON request body, based on another property from that body

当 JSON(使用 Jackson)具有抽象 属性 的对象时,如何正确反序列化该对象的具体实现取决于来自该请求主体的另一个 属性?

这可能最好用一个例子来描述。

我的 REST 端点的请求主体包括一个 属性,它是一个具有多个具体实现的抽象类型,应该根据 discriminator 属性:

反序列化
@Getter
@Builder
@AllArgsConstructor
public class SomeRequestBody {

    @NotNull
    @NotBlank
    @NumberFormat
    private final String discriminator;

    @NotNull
    private final SomeAbstractClass someAbstractClass;

}

摘要 class 有问题

@Getter
@AllArgsConstructor
public abstract class SomeAbstractClass{

    @NotNull
    @NotBlank
    protected final String commonProperty;

}

抽象的示例实现 class

@Getter
public class ConcreteImplementationA extends SomeAbstractClass {

    @Builder
    @JsonCreator
    public ConcreteImplementationA(
        @NotNull @NotBlank @JsonProperty("commonProperty") String commonProperty,
        @NotNull @NotBlank @JsonProperty("specificProperty") Date specificProperty) {
            super(commonProperty);
            this.specificProperty = specificProperty;
    }

    @NotNull
    @NotBlank
    private final String specificProperty;

}

我试过的...

@Getter
@Builder
@AllArgsConstructor
public class SomeRequestBody {

    @NotNull
    @NotBlank
    @NumberFormat
    private final String discriminator;

    @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXTERNAL_PROPERTY, property = "discriminator")
    @JsonSubTypes({
        @JsonSubTypes.Type(value = ConcreteImplementationA.class, name = "1"),
        Other implementations...)
    })
    @NotNull
    private final SomeAbstractClass someAbstractClass;

}

但是,我遇到了以下异常:

"Type definition error: [simple type, class abc.SomeRequestBody]; nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `abc.SomeRequestBody`, problem: Internal error: no creator index for property 'someAbstractClass' (of type com.fasterxml.jackson.databind.deser.impl.FieldProperty)\n at [Source: (PushbackInputStream); line: 8, column: 1]"

实现我需要的正确方法是什么?

事实证明,抽象 属性 的反序列化不是问题,而是不可变属性和 Lombok 的 @AllArgsConstructor 与 Jackson 无法正常工作。我创建了一个带@JsonCreator 注释的构造函数而不是使用注释,现在它工作正常。