我试图将
JSON数组反序列化为使用Jackson的Java Collection.这个动机来自于这个问题的答案,我昨晚
Can I instantiate a superclass and have a particular subclass be instantiated based on the parameters supplied问.
我得到的错误是(可换行添加换行符):
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.StringReader@325aef; 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>>(){});
我的反序列化课程(我们没有打印的公共吸烟者/设定者)列在下面:
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: java.io.StringReader@325aef; 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)
解决方法
经常发生的时候,写出一个问题可以帮助你看到解决方案.所以我需要做两件事情.
首先,我需要将类型信息添加到JSON中 – 这不是我真正想要做的,但我想你需要在某个地方提供这些信息.
然后我需要编辑QueryValue上的注释为:
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME,property = "type")
@JsonSubTypes({
@Type(value = ResourceQueryValue.class,name = "ResourceQueryValue"),@Type(value = NumericQueryValue.class,name= "NumericQueryValue")
})