【问题标题】:How to read value from JSON with Jackson Java如何使用 Jackson Java 从 JSON 中读取值
【发布时间】:2022-01-12 09:18:20
【问题描述】:

我有一个 JSON 文件:

{
    "param": {
        "rows": 1,
        "columns": "4"
    },
    "items": [{
        "name": "A",
        "amount": 33,
        "price": "43"
    }, {
        "name": "B",
        "amount": 43,
        "price": "2"
    }, {
        "name": "C",
        "amount": 45,
        "price": "1"
    }, {
        "name": "D",
        "amount": 543,
        "price": "55" 
   }]
}

我想单独获取这些物品。我尝试做,结果做了null:

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

Items item; // only items
item =  objectMapper.readValue(new File("D:/example/file.json"), Items.class);
System.out.println(item.getAmount());

这是 Items 的类:

public class Items {
    private String name;
    private String amount;
    private double price;

    public Items() {
        super();
    }

    //constructor

    //getters and setters
}

我做错了什么?如何正确读取项目的值?

【问题讨论】:

  • 您应该将类​​Items 重命名为Item 并创建另一个具有成员变量List<Item> items 的类(如Items)。
  • 不明白
  • 换句话说,当您进行转换时,杰克逊希望将 JSON 中的字段放入一个对象中,该对象具有名为 param 的对象以及具有 name 的对象列表、amountprice 字段。因此建议让 ab 对象 Item 保存它,然后将它作为列表包含在主对象中
  • 您试图解析包含param 对象和items 数组的顶级元素到不正确的Items 类中,items 数组包含一个项目数组。所以@LHCHIN 建议您创建另一个包含List<Item> items 的类,然后将其作为类而不是item 传递给readValue 方法
  • 您正在尝试将集合 {Items1, Items2, Items3} 映射到名为 Items 的类,该类不是集合,但仅包含字符串和双字段。

标签: java json jackson-databind


【解决方案1】:

你没有正确处理 JSON 数组 - items - 所以正如我在 OP 下评论的那样,你需要做的就是将原始类 Items 重命名为 Item 并创建另一个类 Items 如下,Jackson 库将为您完成其余的工作:

public class Item {
    private String name;
    private String amount;
    private double price;

    // general getters/setters
}

public class Items {
    private List<Item> items;

    // general getter/setter
}

然后你可以用你的代码 sn-p 反序列化 JSON 字符串:

Items items = objectMapper.readValue(new File("D:/example/file.json"), Items.class);
System.out.println(items.get(0).getAmount());

【讨论】:

    【解决方案2】:

    首先,你需要有一个对象,包含List item,因为JSON文件有多个item,不止一个,你可以参考我的代码

      public class ItemsList {
        private List<Items> items;
    
        public ItemsList () {
        }
    }
    

    我们将修改映射器

            item=  objectMapper.readValue(new File("D:/example/file.json"), ItemsList.class);
    

    但我认为您应该从 Items => Item 更改您的课程

    希望它能帮助你解决问题

    【讨论】:

      【解决方案3】:

      我建议你轻松拥有以下类,Example.java、Param.java、Item.java:

      Example.java:
      
      public class Example {
          private Param param;
          private List<Item> items;
      
          //constructor
      
          //getters and setters
      }
      
      
      Param.java:
      
      public class Param {
      
          private int rows;
          private int columns;
      
          //constructor
      
          //getters and setters
      }
      
      Item.java
      
      public class Item {
          private String name;
          private String amount;
          private double price;
       }
      

      然后你可以写:

       Example  example=  objectMapper.readValue(new File("D:/example/file.json"), 
       Example.class);
      
        for(Item item: example.getItems())
              System.out.println(item.getAmount());
      

      【讨论】:

        【解决方案4】:

        这里的问题是因为您的 JSON 文件的结构与您在 ObjectMapper.readValue 方法(在您的示例中为 Items.class)中作为第二个参数传递的类的结构不对应。您需要对齐两个结构。 根据文件结构,你的Items 文件应该是下一个

        public class Items {
            private Param param;
            private List<Item> items;
        
            // Getters & Setters
        }
        

        另外你需要创建类Param:

        public class Param {
            private Integer rows;
            private Integer columns;
        
            // Getters & Setters
        }
        

        还有班级Item:

        public class Item {
            private String name;
            private String amount;
            private double price;
        
            // Getters & Setters
        }
        

        之后你就可以通过下一个 sn-p 读取你的文件了:

        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        Items items = objectMapper.readValue(new File("D:/example/file.json"), Items.class);
        items.getItems().stream().map(Item::getAmount).forEach(System.out::println);
        

        【讨论】:

          【解决方案5】:

          您应该将其读取为 Map,然后使用您的地图作为源来填充您的项目。此外,还有一个开源库,它具有基于 Jackson 库的功能,真正简化了从 Json 读取/写入对象的过程。如果你有一个 json 字符串,你所要做的就是:

          Map<String, Object> map = JsonUtils.readObjectFromJsonString(jsonString, Map.class);
          

          虽然它会抛出 IOException,所以您需要处理它。这是Javadoc。该库名为 MgntUtils,可以在 Maven artifactGithub 上找到(包括 javadoc 和源代码)

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2023-03-14
            • 2018-04-06
            • 2020-08-05
            • 2014-10-22
            • 1970-01-01
            • 2016-12-08
            • 1970-01-01
            • 2021-03-28
            相关资源
            最近更新 更多