2011-06-22 21 views
13

मैं जैक्सन का उपयोग कर एक जावा संग्रह में एक JSON सरणी deserialize करने की कोशिश कर रहा हूँ। इस सवाल के जवाब से प्रेरित मैंने पिछली रात Can I instantiate a superclass and have a particular subclass be instantiated based on the parameters supplied से पूछा।जैक्सन deserialization ... अप्रत्याशित टोकन (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: java.io.Stri[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 
    } 
] 

मैं उपयोग करना चाहते हैं इस (नीचे) कोड या किसी वस्तु जो Collection<QueryProperty> का एक उदाहरण है जो मुझे बुलाया है पाने के लिए कुछ इसी तरह queryProperties

ObjectMapper mapper = new ObjectMapper(); 
Collection<QueryProperty> queryProperties = 
    queryProperties = mapper.readValue(query, 
     new TypeReference<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

जैसा कि अक्सर होता है एक सवाल लिखने समाधान को देखने में मदद करता है। तो मुझे दो चीजें करने की ज़रूरत है।

सबसे पहले मुझे जेएसओएन में टाइप जानकारी जोड़ने की ज़रूरत है - जो मैं वास्तव में नहीं करना चाहता था, लेकिन मुझे लगता है कि आपको कहीं भी उस जानकारी को प्रदान करने की आवश्यकता है।

और फिर मैं 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 के साथ ऐसा करने की कोशिश कर रहा हूँ। बहुत बहुत धन्यवाद। –

संबंधित मुद्दे