Jackson 反序列化...意外的令牌 (END_OBJECT),

发布于 2024-11-16 11:28:09 字数 3313 浏览 1 评论 0原文

我正在尝试使用 Jackson 将 JSON 数组反序列化为 Java 集合。这是由我昨晚问的这个问题的答案所激发的 我可以实例化一个超类并根据提供的参数实例化一个特定的子类

我得到的错误是(为了可读性而添加换行符):

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
    }
]

我想使用此(下面)代码或类似的代码来获取一个对象,该对象是我称为 queryPropertiesCollection的实例code>

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: 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)

I am trying to deserialize a JSON array into a Java Collection using Jackson. This motivated by the answers to this question I asked last night Can I instantiate a superclass and have a particular subclass be instantiated based on the parameters supplied.

The error I am gettings is (line breaks added for readability):

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"])

My situation is quite complicated. My array contains objects which themselves contain a value which is an array. This array in turn contains values which are also objects but are not necessarily the same (thus polymorphism).

Here is a sample JSON string:

[
    {
      "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
    }
]

I would like to use this (below) code or something similar to get an object which is an instance of Collection<QueryProperty> which I have called queryProperties

ObjectMapper mapper = new ObjectMapper();  
Collection<QueryProperty> queryProperties = 
   queryProperties = mapper.readValue(query, 
      new TypeReference<Collection<QueryProperty>>(){});

My classes for deserialization (they have public getters/setters which I am not printing) are listed below:

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 the same JSON doesn't include an object of this type.

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

Initial part of Stack trace:

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)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

怪异←思 2024-11-23 11:28:09

正如经常发生的那样,写下问题可以帮助您找到解决方案。所以我需要做两件事。

首先,我需要将类型信息添加到 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")
    })  

As often happens, writing out a question helps you see the solution. So I need to do two things.

Firstly I need to add the type information into the JSON - which is not what I really wanted to do, but I guess you need to provide that information somewhere.

And then I need to edit the annotation on QueryValue to be:

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")  
@JsonSubTypes({  
    @Type(value = ResourceQueryValue.class, name = "ResourceQueryValue"),  
    @Type(value = NumericQueryValue.class, name= "NumericQueryValue")
    })  
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文