【问题标题】:Serialization and Deserialization with Jackson Exception杰克逊异常的序列化和反序列化
【发布时间】:2012-12-12 11:49:32
【问题描述】:

JSON nest class data binding 正如答案所做的那样,当我对容器进行序列化和反序列化时,我得到了这个异常:

Caused by: org.codehaus.jackson.map.JsonMappingException: Can not find a Value deserializer for abstract type [simple type, class com.xiaonei.wap.ps.model.Container]
at org.codehaus.jackson.map.deser.StdDeserializerProvider._handleUnknownValueDeserializer(StdDeserializerProvider.java:321)
at org.codehaus.jackson.map.deser.StdDeserializerProvider.findValueDeserializer(StdDeserializerProvider.java:116)
at org.codehaus.jackson.map.deser.StdDeserializer.findDeserializer(StdDeserializer.java:260)
at

【问题讨论】:

    标签: java json jackson


    【解决方案1】:

    只需删除或重命名 type 字段的 setter/getter

    public class Container 
    {
       private AAnimal animal;
    
       public AAnimal getAnimal()
       {
          return animal;
       }
    
       @JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include=JsonTypeInfo.As.EXTERNAL_PROPERTY, property="type")
       @JsonSubTypes({ @Type(value = Cat.class, name = "cat"), @Type(value = Dog.class, name = "dog") })
       public void setAnimal(AAnimal animal)
       {
          this.animal = animal;
       }
    }    
    
    public abstract class AAnimal 
    {
       public String name;
    }  
    

    测试

      String json = "{\"type\":\"cat\", \"animal\" : {\"name\":\"cat-mew\" }}";
      Container val = o.readValue(json, Container.class);
      System.out.println(o.writeValueAsString(val));  
    

    输出是

    {"animal":{"name":"cat-mew"},"type":"cat"}
    

    【讨论】:

    • 如果我删除类型字段,我得到了这个:org.codehaus.jackson.map.exc.UnrecognizedPropertyException: Unrecognized field "type" (Class com.chat.jsonobject.Message),未标记为无视
    【解决方案2】:

    正如您提供的链接的答案中提到的,您需要明确提及对象的type 作为外部属性,因为该类型不属于父类。这个JsonTypeInfo.As.EXTERNAL_PROPERTY 将 type 属性添加到上层层次结构中。

    因此,这个type 作为外部属性应该存在于转换后的片段中。因此,当您从 json 中删除 type 时,该属性没有明确的默认实现。这就是为什么需要在注解的defaultImpl参数中添加一个默认的实现类。

    因此,要解决此问题,您可以将AAnimal.class 添加为defaultImpl

    @JsonTypeInfo(
            use = JsonTypeInfo.Id.NAME,
            include = JsonTypeInfo.As.EXTERNAL_PROPERTY,
            property = "type",
            defaultImpl = AAnimal.class
    )
    @JsonSubTypes({ 
        @Type(value = Cat.class, name = "cat"), 
        @Type(value = Dog.class, name = "dog") 
    })
    public void setAnimal(Animal animal) {
        this.animal = animal;
    }
    

    现在,如果您从输入 json 中省略 type,并使用以下命令进行测试:

    String json = "{\"animal\" : {\"name\":\"cat-mew\" }}";
    

    你会得到:

    {"animal":{"name":"cat-mew"},"type":"AAnimal"}
    

    【讨论】:

      猜你喜欢
      • 2015-04-07
      • 1970-01-01
      • 2012-09-10
      • 2012-11-07
      • 1970-01-01
      • 1970-01-01
      • 2012-11-19
      • 2016-10-23
      相关资源
      最近更新 更多