2

我有一个 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;
        }
    }

我正在使用 Jackson 库对它们进行反序列化:

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 的实例

4

2 回答 2

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 所说的 aThirdField是:

{
    "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对象做同样的事情。

于 2012-11-28T08:42:30.927 回答
0

注意: 我是EclipseLink JAXB (MOXy)负责人,也是JAXB (JSR-222)专家组的成员。

由于并非总是可以更改您的域模型(由 @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);
}

输入.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
   } ]
}

了解更多信息

于 2012-11-28T11:22:12.157 回答