使用jackson JsonTypeInfo属性作为ENUM反序列化动态json?

时间:2016-08-29 15:55:34

标签: java json enums jackson deserialization

我试图从动态JSON中获取java对象。  这些给定类来自第三方API的重要一点。

    @JsonTypeInfo(
        use = Id.NAME,
        include = As.PROPERTY,
        property = "nodeType"
    )
    @JsonSubTypes({    @Type(
            name = "Filter",
            value = Filter.class
        ),     @Type(
            name = "Criterion",
            value = Criterion.class
        )})
    public abstract class Node {
        public Node() {
        }

        @JsonIgnore
        public EvaluationResult evaluate(Map<UUID, List<AnswerValue>> answers) {
            Evaluator evaluator = new Evaluator();
            return evaluator.evaluateAdvancedLogic(this, answers);
        }
    }
Filter.java

@JsonInclude(Include.NON_NULL)
@JsonPropertyOrder({"evaluationType", "filters"})
public class Filter extends Node {
    @JsonProperty("evaluationType")
    private EvaluationType evaluationType;
    @NotNull
    @JsonProperty("filters")
    @Valid
    private List<Node> filters = new ArrayList();
    @JsonIgnore
    private Map<String, Object> additionalProperties = new HashMap();

    public Filter() {
    }

    @JsonProperty("evaluationType")
    public EvaluationType getEvaluationType() {
        return this.evaluationType;
    }

    @JsonProperty("evaluationType")
    public void setEvaluationType(EvaluationType evaluationType) {
        this.evaluationType = evaluationType;
    }

    @JsonProperty("filters")
    public List<Node> getFilters() {
        return this.filters;
    }

    @JsonProperty("filters")
    public void setFilters(List<Node> filters) {
        this.filters = filters;
    }

    public String toString() {
        return ToStringBuilder.reflectionToString(this);
    }

    @JsonAnyGetter
    public Map<String, Object> getAdditionalProperties() {
        return this.additionalProperties;
    }
}

Criterion.java

@JsonInclude(Include.NON_NULL)
@JsonPropertyOrder({"fieldSourceType", "fieldCategoryName", "sequenceNumber", "fieldName", "values", "operator", "fieldId"})
public class Criterion extends Node {
    @JsonProperty("fieldSourceType")
    private FieldSourceType fieldSourceType;
    @JsonProperty("fieldCategoryName")
    private String fieldCategoryName;
    @NotNull
    @JsonProperty("sequenceNumber")
    private Long sequenceNumber;
    @JsonProperty("fieldName")
    private String fieldName;
    @JsonProperty("values")
    @Valid
    private List<String> values = new ArrayList();
    @JsonProperty("operator")
    @Valid
    private Operator operator;
    @NotNull
    @JsonProperty("fieldId")
    private UUID fieldId;
    @JsonIgnore
    private Map<String, Object> additionalProperties = new HashMap();

    public Criterion() {
    }

    @JsonProperty("fieldSourceType")
    public FieldSourceType getFieldSourceType() {
        return this.fieldSourceType;
    }

    @JsonProperty("fieldSourceType")
    public void setFieldSourceType(FieldSourceType fieldSourceType) {
        this.fieldSourceType = fieldSourceType;
    }

    @JsonProperty("fieldCategoryName")
    public String getFieldCategoryName() {
        return this.fieldCategoryName;
    }

    @JsonProperty("fieldCategoryName")
    public void setFieldCategoryName(String fieldCategoryName) {
        this.fieldCategoryName = fieldCategoryName;
    }

    @JsonProperty("sequenceNumber")
    public Long getSequenceNumber() {
        return this.sequenceNumber;
    }

    @JsonProperty("sequenceNumber")
    public void setSequenceNumber(Long sequenceNumber) {
        this.sequenceNumber = sequenceNumber;
    }

    @JsonProperty("fieldName")
    public String getFieldName() {
        return this.fieldName;
    }

    @JsonProperty("fieldName")
    public void setFieldName(String fieldName) {
        this.fieldName = fieldName;
    }

    @JsonProperty("values")
    public List<String> getValues() {
        return this.values;
    }

    @JsonProperty("values")
    public void setValues(List<String> values) {
        this.values = values;
    }

    @JsonProperty("operator")
    public Operator getOperator() {
        return this.operator;
    }

    @JsonProperty("operator")
    public void setOperator(Operator operator) {
        this.operator = operator;
    }

    @JsonProperty("fieldId")
    public UUID getFieldId() {
        return this.fieldId;
    }

    @JsonProperty("fieldId")
    public void setFieldId(UUID fieldId) {
        this.fieldId = fieldId;
    }
}

用于转换的json就是这个。

{
   "evaluationType":"AND",
   "nodeType":"Criterion",
   "Criterion":[
       {

           "fieldName":"sdada",
           "values":"sdad",
           "operator":{
               "operatorType":"Equals"
           }
       },
       {
           "nodeType":"Criterion",
           "fieldName":"dasa",
           "values":"das",
           "operator":{
               "operatorType":"Equals"
           }
       },
       {
           "nodeType":"Criterion",
           "fieldName":"dada",
           "values":"dads",
           "operator":{
               "operatorType":"Equals"
           }
       }
       ]

}

问题是此JSON的反序列化失败,并出现以下错误:

{
  "message": "Class com.cvent.logic.model.Criterion is not assignable to com.cvent.logic.model.Filter"
}

1 个答案:

答案 0 :(得分:0)

JSON的第一部分是错误的

 {
   "evaluationType":"AND",
   "nodeType":"Criterion",
   "Criterion":[

它表示类型为标准,但它的评估类型来自过滤器

此外,"Criterion" : [可能应为"filters" : [