J'essaye de désérialiser un tableau JSON dans une collection Java en utilisant Jackson. Cela motivé par les réponses à cette question que j'ai demandé hier soir Can I instantiate a superclass and have a particular subclass be instantiated based on the parameters supplied.Désérialisation de Jackson ... Jeton inattendu (END_OBJECT),
L'erreur que je suis Gettings est (sauts de ligne ajoutée pour la lisibilité):
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"])
Ma situation est assez compliquée. Mon tableau contient des objets qui eux-mêmes contiennent une valeur qui est un tableau. Ce tableau contient à son tour des valeurs qui sont aussi des objets mais ne sont pas nécessairement les mêmes (donc polymorphisme).
Voici une chaîne JSON exemple:
[
{
"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
}
]
Je voudrais utiliser (ci-dessous) code ou quelque chose de similaire pour obtenir un objet qui est une instance de Collection<QueryProperty>
que j'ai appelé queryProperties
ObjectMapper mapper = new ObjectMapper();
Collection<QueryProperty> queryProperties =
queryProperties = mapper.readValue(query,
new TypeReference<Collection<QueryProperty>>(){});
Mes classes pour désérialisation (ils ont getters publics/setters que je ne suis pas l'impression) sont énumérés ci-dessous:
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
même JSON ne comprend pas un objet de ce type.
public class NumericQueryValue extends QueryValue{
double lower;
double upper;
}
partie initiale de la trace de pile:
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)
Oui, une information de type supplémentaire doit être ajouté d'une certaine façon. Pour ce que cela vaut, le nom par défaut pour les sous-types doit être un nom de type non qualifié (ce que vous avez). Mais c'est probablement une bonne idée d'être explicite, juste au cas où. – StaxMan
Comment avez-vous ajouté le type d'information @ankur. J'essaye de faire ça avec angularJS. Merci beaucoup. –