【问题标题】:Can not deserialize JSON with Jackson lib无法使用 Jackson lib 反序列化 JSON
【发布时间】:2012-11-28 19:22:12
【问题描述】:

我有一个 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 的实例

【问题讨论】:

    标签: java json jackson


    【解决方案1】:

    您将 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 对象执行相同的操作。

    【讨论】:

      【解决方案2】:

      注意:我是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/Output

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

      更多信息

      【讨论】:

        猜你喜欢
        • 2018-12-16
        • 2013-01-08
        • 1970-01-01
        • 2015-03-13
        • 2016-04-25
        • 1970-01-01
        • 1970-01-01
        • 2021-05-28
        • 2015-10-02
        相关资源
        最近更新 更多