Jackson abstract class 基于参数值的反序列化

Jackson abstract class deserialization based on parameter value

我想反序列化以下 JSON 字符串:

{
    "name": "name",
    "id": "id",
    "requirements": [
        {
            "requirement_type": "hard", // 'soft' or 'hard'
            "parameters": {
                "first": "value_1",
                "second": "value_2",
                "third": "value_3"
            }
        }
    ]
}

进入下一个 DTO:

@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class OwnObject {
    private String name;
    private String id;
    private List<Requirement> requirement;

    // getters & setters
}

@JsonInclude(JsonInclude.Include.NON_EMPTY)
public abstract class Requirement {
    private String requirement_type;
    private List<Parameter> parameters;

    // getters & setters
}

@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class SoftRequirement {
}

@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class HardRequirement {
}

@JsonInclude(JsonInclude.Include.NON_EMPTY)
public abstract class Parameter {
}

@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class SoftParameter {
    private String first;

    // getter & setter
}

@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class HardParameter {
    private String first;
    private String second;
    private String third;

    // getters & setters
}

映射应该基于 'requirement_type' 属性完成,例如: 如果'soft' 那么SoftRequirement 和SoftParameter 就在那里面。 如果'hard'那么HardRequirement和HardParameter就在那里面。

试图用这个来处理:

@JsonInclude(JsonInclude.Include.NON_EMPTY)
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "requirement_type")
@JsonSubTypes( {
        @JsonSubTypes.Type(value = SoftRequirement.class, name = "soft"),
        @JsonSubTypes.Type(value = HardRequirement.class, name = "hard")
} )

@JsonInclude(JsonInclude.Include.NON_EMPTY)
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "requirement_type", include = JsonTypeInfo.As.EXTERNAL_PROPERTY)
@JsonSubTypes( {
        @JsonSubTypes.Type(value = SoftParameter.class, name = "soft"),
        @JsonSubTypes.Type(value = HardParameter.class, name = "hard")
} )

在上层(Requirement)它实现了类型但没有在子类中填充'requirement_type'。 在较低级别(参数),它失败了,因为它没有从较高级别找到 'requirement_type'。

我假设 JSON 是您数据的正确表示:在 JSON 中,parameters 字段是一个对象实例,在您的实现是一个列表。

here 所述,JsonTypeInfo.As.EXTERNAL_PROPERTY 只能用于属性。

因此,您必须将所有注释从 Parameter class 移动到 属性 parameterssetParameters(...) 方法 Requirement class.

Requirement 实现将允许 Jackson 正确反序列化单个参数对象:

@JsonInclude(JsonInclude.Include.NON_EMPTY)
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "requirement_type", visible = true)
@JsonSubTypes( {
        @JsonSubTypes.Type(value = SoftRequirement.class, name = "soft"),
        @JsonSubTypes.Type(value = HardRequirement.class, name = "hard")
} )
public abstract class Requirement {
    private String requirement_type;
    private Parameter parameters;

    public String getRequirement_type() {
        return this.requirement_type;
    }

    public void setRequirement_type(String requirement_type) {
        this.requirement_type = requirement_type;
    }

    public Parameter getParameters() {
        return this.parameters;
    }

    @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "requirement_type", include = JsonTypeInfo.As.EXTERNAL_PROPERTY)
    @JsonSubTypes( {
            @JsonSubTypes.Type(value = SoftParameter.class, name = "soft"),
            @JsonSubTypes.Type(value = HardParameter.class, name = "hard")
    } )
    public void setParameters(Parameter parameters) {
        this.parameters = parameters;
    }
}