Server returns such part of JSON:
{\"condition\": {
\"or\": [
{
\"and\": [
{
\"operand\": \"a\",
You should use a class, not an interface. Otherwise, Jackson cannot create an instance.
I believe you also need to create default (aka no-arg) constructors for your POJOs for Jackson to work.
Also, a good general approach for creating a Jackson mapping is to instantiate a Java instance of your classes and then create the JSON from that, Java -> JSON. This makes it much easier to understand how the mapping is different - going from JSON -> Java is harder to debug.
I had to accomplish something very similar, here is an excerpt.
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "@class")
@JsonSubTypes({
@JsonSubTypes.Type(value=IMetricCollection.class, name="MetricCollection"),
@JsonSubTypes.Type(value=IMetricDouble.class, name="MetricDouble"),
@JsonSubTypes.Type(value=IMetricInteger.class, name="MetricInteger"),
@JsonSubTypes.Type(value=IMetricPlot.class, name="MetricPlot"),
@JsonSubTypes.Type(value=IMetricString.class, name="MetricString"),
@JsonSubTypes.Type(value=IMetricMatrix.class, name="MetricMatrix")
})
public interface IMetric extends HasViolations<IViolation>, Serializable {
/**
* Getter for the name of the object.
*
* @return
*/
public abstract String getName();
/**
* Set the name of the object.
*
* @param name
*/
public abstract void setName(String name);
/**
* Returns true if metric has violations.
* @return
*/
public abstract boolean hasMetricViolations();
}
This may seem kind of counter intuitive for using an interface but I was able to get this all working by telling the interface what concrete class to use. I also have another chunk of code in a separate project that overrides the JsonSubTypes
to instantiate it's own type of classes below, if this helps.
@JsonDeserialize(as=MetricMatrix.class)
public interface IMetricMatrix<C extends IColumn> extends IMetric {
public static interface IColumn extends IMetricCollection<IMetric> {
}
public static interface IIntegerColumn extends IColumn {
}
public static interface IDoubleColumn extends IColumn {
}
public static interface IStringColumn extends IColumn {
}
public abstract List<C> getValue();
public abstract void setValue(List<C> value);
public abstract void addColumn(C column);
}
In this class I can parse the same REST message but I am overriding the original projects concrete types and the subtypes for this project make them persistent. Since the type names are the same I can override what interface to use for this object type. Please keep in mind that I am using the @class property but this is completely arbitrary could be @whatever annotation but it would need to match on both sides. This is not using the JsonTypeInfo.Id.Class
annotation.
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "@class")
@JsonSubTypes({
@JsonSubTypes.Type(value=IMetricCollectionEntity.class, name="MetricCollection"),
@JsonSubTypes.Type(value=IMetricDoubleEntity.class, name="MetricDouble"),
@JsonSubTypes.Type(value=IMetricIntegerEntity.class, name="MetricInteger"),
@JsonSubTypes.Type(value=IMetricPlotEntityEntity.class, name="MetricPlot"),
@JsonSubTypes.Type(value=IMetricStringEntity.class, name="MetricString"),
@JsonSubTypes.Type(value=IMetricMatrixEntity.class, name="MetricMatrix")
})
public interface IMetricEntity extends IDatastoreObject, IMetric {
public String getContext();
public List<IViolation> getViolations();
}
@JsonDeserialize(as=MetricMatrixEntity.class)
public interface IMetricMatrixEntity extends IMetricEntity {
public static interface IColumnEntity extends IColumn {
public String getName();
}
public static interface IIntegerColumnEntity extends IColumnEntity {
}
public static interface IDoubleColumnEntity extends IColumnEntity {
}
public static interface IStringColumnEntity extends IColumnEntity {
}
public abstract List<IColumnEntity> getValue();
public abstract void setValue(List<IColumnEntity> value);
public abstract void addColumn(IColumnEntity column);
}