无法用Jackson lib反序列化JSON

时间:2012-11-28 08:39:08

标签: java json jackson

我有一个JSON:

{
    "firstField": "Something One",
    "secondField": "Something Two",
    "thirdField": [
        {
            "thirdField_one": "Something Four",
            "thirdField_two": "Something Five"
        },
        {
            "thirdField_one": "Something Six",
            "thirdField_two": "Something Seven"
        }
    ],
    "fifthField": [
        {
            "fifthField_one": "Something… ",
            "fifthField_two": "Something...",
            "fifthField_three": 12345
        },
        {
            "fifthField_one": "Something",
            "fifthField_two": "Something",
            "fifthField_three": 12345
        }
    ]
}

我有我的课程:

public static class MyClass {
        @JsonProperty
        private String firstField, secondField;
        @JsonProperty
        private ThirdField thirdField;
        @JsonProperty
        private FifthField fifthField;

        public static class ThirdField {
            private List<ThirdFieldItem> thirdField;
        }

        public static class ThirdFieldItem {
            private String thirdField_one, thirdField_two;
        }

        public static class FifthField {
            private List<FifthFieldItem> fifthField;
        }

        public static class FifthFieldItem {
            private String fifthField_one, fifthField_two;
            private int fifthField_three;
        }
    }

我用杰克逊图书馆对它们进行反序列化:

public void testJackson() throws IOException {
    JsonFactory factory = new JsonFactory();
    ObjectMapper mapper = new ObjectMapper(factory);
    File from = new File("text.txt"); // JSON I mentioned above
    mapper.readValue(from, MyClass.class);
}

但是我得到了例外:

  

org.codehaus.jackson.map.JsonMappingException:无法反序列化   在START_ARRAY令牌中使用Main $ MyClass $ ThirdField的实例

2 个答案:

答案 0 :(得分:5)

您已将thirdFieldfifthField属性定义为JSON中的数组。它们也需要是Java bean上的数组或集合:

public static class MyClass {
    @JsonProperty
    private String firstField, secondField;

    @JsonProperty
    private Collection<ThirdField> thirdField;

    @JsonProperty
    private Collection<FifthField> fifthField;

    /// ...
}

当您浏览并将现有JSON对象转换为bean时,请记住JSON数据非常类似于地图。如果您想象如何将地图中的数据映射到对象中,它确实有帮助。您的ThirdFieldFifthField对象需要映射JSON中的定义。这就是您的JSON所说的ThirdField

{
    "thirdField_one": "Something Four",
    "thirdField_two": "Something Five"
}

直接将其转换为Java bean会为您提供:

public class ThirdField implements Serializable {
    private String thirdField_one;
    private String thirdField_two;

    // ...
}

您可以添加注释等,以获得完整的成熟bean。对FifthField对象执行相同的操作。

答案 1 :(得分:0)

注意:我是EclipseLink JAXB (MOXy)潜在客户和JAXB (JSR-222)专家组的成员。

由于无法始终更改域模型(如answered by @Perception),因此下面是使用MOXy将原始对象模型映射到所需JSON的方法。

Java模型

在此用例中,您可以使用@XmlPath(".")扩展名。这告诉MOXy将目标对象的内容带入源节点。

@XmlAccessorType(XmlAccessType.FIELD)
public static class MyClass {
    private String firstField, secondField;

    @XmlPath(".")
    private ThirdField thirdField;

    @XmlPath(".")
    private FifthField fifthField;

    @XmlAccessorType(XmlAccessType.FIELD)
    public static class ThirdField {
        private List<ThirdFieldItem> thirdField;
    }

    @XmlAccessorType(XmlAccessType.FIELD)
    public static class ThirdFieldItem {
        private String thirdField_one, thirdField_two;
    }

    @XmlAccessorType(XmlAccessType.FIELD)
    public static class FifthField {
        private List<FifthFieldItem> fifthField;
    }

    @XmlAccessorType(XmlAccessType.FIELD)
    public static class FifthFieldItem {
        private String fifthField_one, fifthField_two;
        private int fifthField_three;
    }
}

转换代码

下面的演示代码显示了如何启用MOXy的JSON绑定。

public static void main(String[] args) throws Exception {
    Map<String, Object> properties = new HashMap<String, Object>(2);
    properties.put(JAXBContextProperties.MEDIA_TYPE, "application/json");
    properties.put(JAXBContextProperties.JSON_INCLUDE_ROOT, false);
    JAXBContext jc = JAXBContext.newInstance(new Class[] {MyClass.class}, properties);

    Unmarshaller unmarshaller = jc.createUnmarshaller();
    StreamSource json = new StreamSource("src/forum13600952/input.json");
    MyClass myClass = unmarshaller.unmarshal(json, MyClass.class).getValue();

    Marshaller marshaller = jc.createMarshaller();
    marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
    marshaller.marshal(myClass, System.out);
}

<强> input.json /输出

Belos是您稍微重新格式化的问题的输入,以匹配MOXy产生的输出。

{
   "firstField" : "Something One",
   "secondField" : "Something Two",
   "thirdField" : [ {
      "thirdField_one" : "Something Four",
      "thirdField_two" : "Something Five"
   }, {
      "thirdField_one" : "Something Six",
      "thirdField_two" : "Something Seven"
   } ],
   "fifthField" : [ {
      "fifthField_one" : "Something...",
      "fifthField_two" : "Something...",
      "fifthField_three" : 12345
   }, {
      "fifthField_one" : "Something",
      "fifthField_two" : "Something",
      "fifthField_three" : 12345
   } ]
}

了解更多信息