简体   繁体   中英

Deserialize dynamic json using jackson JsonTypeInfo property as ENUM?

I am trying to get java object from dynamic JSON. One Important point these given classes are from third party 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;
    }
}

The json used to conversion is this.

{
   "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"
           }
       }
       ]

}

The problem is that deserialization of this JSON fails with following error:

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

The first part of the JSON is wrong

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

It says that the type is Criterion but it has evaluationType from Filter .

Also, probably "Criterion" : [ should be "filters" : [

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM