2016-12-23 44 views
1

我想編寫使用傑克遜序列化/反序列化對象的代碼。傑克遜序列化和相關令牌(END_OBJECT),預計FIELD_NAME:缺少屬性'名稱'

的對象在本質上是多態:

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "name") 
@JsonSubTypes({ 
    @Type(value = ComparableQuery.class), 
    @Type(value = CompositeQuery.class) 
}) 
public abstract class BaseQuery { 

    private final Long characteristicId; 

... 
} 

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "name") 
public class CompositeQuery extends BaseQuery { 

    private final String operator; 
    private final BaseQuery[] queries; 

    public CompositeQuery(Long characteristicId, Operator operator, BaseQuery... queries) { 
     super(characteristicId); 
     this.operator = operator.value; 
     this.queries = queries; 
    } 

... 
} 

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "name") 
@JsonSubTypes({ 
    @Type(value = EqualQuery.class), 
    @Type(value = GreaterOrEqualQuery.class), 
    @Type(value = GreaterQuery.class), 
    @Type(value = LessOrEqualQuery.class), 
    @Type(value = LessQuery.class) 
}) 
public abstract class ComparableQuery extends BaseQuery { 

    private final Object value; 

    private final String comparisonOperator; 

... 
} 

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "name") 
public class EqualQuery extends ComparableQuery { 

    public EqualQuery(Long characteristicId, Object value) { 
     super(characteristicId, value, "="); 
    } 

} 

我創建了一個Set<BaseQuery>用下面的代碼:

Set<BaseQuery> queries = new HashSet<>(); 

    BaseQuery megapixelCharacteristicQuery = new CompositeQuery(megapixelCharacteristic.getCharacteristicId(), CompositeQuery.Operator.AND, new GreaterOrEqualQuery(megapixelCharacteristic.getCharacteristicId(), 10), new LessOrEqualQuery(megapixelCharacteristic.getCharacteristicId(), 50)); 
    queries.add(megapixelCharacteristicQuery); 

現在,當我試圖序列我收到了以下JSON對象:

[ 
    { 
     "characteristicId":391, 
     "operator":"AND", 
     "queries":[ 
     { 
      "name":"GreaterOrEqualQuery", 
      "characteristicId":391, 
      "value":10, 
      "comparisonOperator":">=" 
     }, 
     { 
      "name":"LessOrEqualQuery", 
      "characteristicId":391, 
      "value":50, 
      "comparisonOperator":"<=" 
     } 
     ] 
    } 
] 

但是當我嘗試反序列化JSON文件時,我接收以下情況除外:

com.fasterxml.jackson.databind.JsonMappingException: Unexpected token (END_OBJECT), expected FIELD_NAME: missing property 'name' that is to contain type id (for class com.example.decision.query.characteristic.BaseQuery) 
at [Source: [{"characteristicId":391,"operator":"AND","queries":[{"name":"GreaterOrEqualQuery","characteristicId":391,"value":10,"comparisonOperator":">="},{"name":"LessOrEqualQuery","characteristicId":391,"value":50,"comparisonOperator":"<="}]}]; line: 1, column: 233] (through reference chain: java.util.HashSet[0]) 
    at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:261) 

對於某些原因name字段是JSON根對象不存在。

如何解決?

修訂

它工作正常,當我試圖序列例如只megapixelCharacteristicQuery對象:

BaseQuery megapixelCharacteristicQuery = new CompositeQuery(megapixelCharacteristic.getCharacteristicId(), CompositeQuery.Operator.AND, new GreaterOrEqualQuery(megapixelCharacteristic.getCharacteristicId(), 10), new LessOrEqualQuery(megapixelCharacteristic.getCharacteristicId(), 50)); 

在這種情況下,傑克遜形成以下JSON(用正確"name":"CompositeQuery"):

{ 
    "name":"CompositeQuery", 
    "characteristicId":391, 
    "operator":"AND", 
    "queries":[ 
     { 
     "name":"GreaterOrEqualQuery", 
     "characteristicId":391, 
     "value":10, 
     "operator":">=" 
     }, 
     { 
     "name":"LessOrEqualQuery", 
     "characteristicId":391, 
     "value":50, 
     "operator":"<=" 
     } 
    ] 
} 

但是當序列化/反序列化仍然不起作用時megapixelCharacteristicQuery位於HashSet<BaseQuery>之內。

如何使它與HashSet一起工作?

而且,甚至開始用HashSet做工精細當我添加defaultImpl = CompositeQuery.classJsonTypeInfo註釋,例如:

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "name", defaultImpl = CompositeQuery.class) 
@JsonSubTypes({ 
    @Type(value = ComparableQuery.class), 
    @Type(value = CompositeQuery.class) 
}) 
public abstract class BaseQuery { 
... 
} 

,但它是不是一種選擇我,因爲我不知道是什麼類型應在不同的情況下使用,所以我仍然在尋找解決方案如何在我的JSON中正確提供name參數。

+0

你是否檢查過你想要序列化的對象上設置的名稱? –

+0

正如你可以看到我的問題,名稱字段只設置在嵌套對象 – alexanoid

+0

但由於某種原因名稱字段未設置爲'CompositeQuery'對象,現在我不明白爲什麼.. – alexanoid

回答