2011-06-22 15 views
13

ジャクソンを使用してJSON配列をJavaコレクションにデシリアライズしようとしています。これは私が昨夜質問したこの質問への回答によって動機づけられましたCan I instantiate a superclass and have a particular subclass be instantiated based on the parameters suppliedジャーナルの逆シリアル化...予期しないトークン(END_OBJECT)、

私はgettings午前エラーが(改行は読みやすくするために追加された)である:

org.codehaus.jackson.map.JsonMappingException: 
    Unexpected token (END_OBJECT), expected FIELD_NAME: missing property 'type' 
    that is to contain type id (for class sempedia.model.query.QueryValue) 
at [Source: [email protected]; line: 1, column: 175] 
    (through reference chain: sempedia.model.query.QueryProperty["values"]) 

私の状況は非常に複雑です。私の配列は、それ自身が配列である値を含むオブジェクトを含んでいます。この配列には、オブジェクトでもあるが必ずしも同じではない(したがって、多型性)値が含まれています。ここで

サンプルJSON文字列です:

[ 
    { 
     "id":"74562", 
     "uri":"http://dbpedia.org/ontology/family", 
     "name":"family", 
     "values":[ 
     { 
      "id":"74563", 
      "uri":"http://dbpedia.org/resource/Orycteropodidae", 
      "name":"Orycteropodidae" 
     } 
     ], 
     "selected":false 
    }, 
    { 
     "id":"78564", 
     "uri":"http://dbpedia.org/ontology/someNumber", 
     "name":"someNumber", 
     "values":[ 
     { 
      "lower":"45", 
      "upper":"975", 
     } 
     ], 
     "selected":true 
    } 
] 

私はこれ(下)のコードまたは私はqueryProperties

ObjectMapper mapper = new ObjectMapper(); 
Collection<QueryProperty> queryProperties = 
    queryProperties = mapper.readValue(query, 
     new TypeReference<Collection<QueryProperty>>(){}); 
と呼ばれている Collection<QueryProperty>のインスタンスであるオブジェクトを取得すると同様のものを使用したいと思います

私には、非公開のgetters/settersがあります。私は印刷しません。

public class QueryProperty {  
    int id; 
    String uri; 
    String name; 
    Set<QueryValue> values; 
    String selected; 
} 

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type") 
@JsonSubTypes({ 
    @Type(value = ResourceQueryValue.class), 
    @Type(value = NumericQueryValue.class) 
    }) 
public abstract class QueryValue { 
    String type; 
} 

ResourceQueryValue

public class ResourceQueryValue extends QueryValue{ 
    int id; 
    String uri; 
    String name; 
} 

NumericQueryValue同じJSONは、このタイプのオブジェクトが含まれていません。スタックトレースの

public class NumericQueryValue extends QueryValue{ 
    double lower; 
    double upper; 
} 

最初の部分:

org.codehaus.jackson.map.JsonMappingException: Unexpected token (END_OBJECT), expected FIELD_NAME: missing property 'type' that is to contain type id (for class sempedia.model.query.QueryValue) 
at [Source: [email protected]; line: 1, column: 175] (through reference chain: sempedia.model.query.QueryProperty["values"]) 
    at org.codehaus.jackson.map.JsonMappingException.from(JsonMappingException.java:163) 
    at org.codehaus.jackson.map.deser.StdDeserializationContext.wrongTokenException(StdDeserializationContext.java:240) 
    at org.codehaus.jackson.map.jsontype.impl.AsPropertyTypeDeserializer.deserializeTypedFromObject(AsPropertyTypeDeserializer.java:86) 
    at org.codehaus.jackson.map.deser.AbstractDeserializer.deserializeWithType(AbstractDeserializer.java:89) 

答えて

15

のように頻繁に質問を書いて、たまたまあなたが解決策を確認できます。だから私は2つのことをする必要があります。

まずJSONにタイプ情報を追加する必要があります。これは本当にやりたいことではありませんが、どこかでその情報を提供する必要があると思います。

そして私がするQueryValueに注釈を編集する必要があります。

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type") 
@JsonSubTypes({ 
    @Type(value = ResourceQueryValue.class, name = "ResourceQueryValue"), 
    @Type(value = NumericQueryValue.class, name= "NumericQueryValue") 
    }) 
+0

はい、余分なタイプの情報はいくつかの方法を追加する必要があります。それが価値があるのであれば、サブタイプのデフォルト名は非修飾型(これはあなたが持っているもの)でなければなりません。しかし、場合によっては明示的にするのはおそらく良い考えです。 – StaxMan

+2

どのようにタイプ情報@ankurを追加しましたか?私はangularJSでそれをしようとしています。どうもありがとうございます。 –

関連する問題