如何使用Jackson在JSONArray-to-List <myobject>中映射不同类型的对象?</myobject>

时间:2013-05-10 21:43:02

标签: java jackson

我有一个类似的JSONObject:

  {
   "name": "John",
   "details": [
      [
       "phone",
       123456789
      ],
      [
       "address",
       "abcdef"
      ]
   ]
}

我正在尝试将上面的jSON映射到以下对象:

 @JsonIgnoreProperties(ignoreUnknown = true)
 public class Employee{
       String name;
       List<List<DetailItem>> details;


       public String getName() {
       return name;
       }
       public void setName(String name) {
      this.name = name;
       }
       public List<List<DetailItem>> getDetails() {
      return details;
       }
       public void setDetails(List<List<DetailItem>> details) {
      this.details = details;
       }

    }


     @JsonSubTypes({
       @JsonSubTypes.Type(value=String.class),
       @JsonSubTypes.Type(value=Integer.class)
       })
    public class DetailItem{

    }

映射使用:

     ObjectMapper mapper = new ObjectMapper();
     mapper.readValue(instream, Employee.class)

例外:

com.fasterxml.jackson.databind.JsonMappingException: Can not instantiate value of type [simple type, DetailItem] from String value; no single-String constructor/factory method (through reference chain: Employe["details"])

我正在尝试进行多态反序列化,因为DetailItemStringInteger

由于

1 个答案:

答案 0 :(得分:1)

这只是 多态反序列化的工作原理!您忽略了多态性的定义,并试图在不相关的类之间神奇地创建关系。即使未明确强制执行,使用@JsonSubTypes注释的类型也应该是每个已定义的@Type的父类。

@JsonSubTypes({
    @Type(value=String.class), // String is not a subclass of DetailItem!
    @Type(value=Integer.class) // Integer is not a subclass of DetailItem!
})
public class DetailItem{
}

根本问题是设计非常糟糕的JSON输入。我甚至不会问为什么每个detail属性都被非规范化并存储到单独的数组中,但我强烈建议将格式修改为更合理的格式。例如:

{
    "name": "John",
    "details": {
        "phone" : 123456789,
        "address" : "abcedf",
    }
}

上述内容可以简单地反序列化为以下对象:

class Employee {
    private Sting name;
    private Map<String, Object> details;

    // constructor, getters/setters
}

如果您坚持使用当前格式,请将List<List<DetailItem>>更改为List<List<Object>>implement a custom deserializer