【问题标题】:Is there a way to make use of Jackson ObjectMapper to read the object from JSON one by one有没有办法利用 Jackson ObjectMapper 从 JSON 中逐个读取对象
【发布时间】:2021-04-21 10:38:47
【问题描述】:

我想知道是否可以利用ObjectMapper 中的Jackson 来逐一读取事件。

我有一个大型 JSON 文件,其中包含许多需要转换为 XML 的事件。我不想将完整的 JSON 事件加载到我的内存中,而是想一个一个地处理事件。因此,我正在使用 Java Jackson 库,它可以遍历 JSON 文件并一次获取单个 JSON 事件,然后我可以将其转换为 XML。这样,一次只会将一个事件加载到内存中。

我知道我可以使用来自 Jackson 的 JsonParser,它将逐个遍历 JSON 文件,但这样我需要处理很多事情。

我有从 XSD 创建的 Java 类(使用 JAXB2)所以我正在考虑使用来自 JacksonObjectMapper 类,它可以直接将每个事件映射到其对应的 Java 类,稍后我可以使用它来转换使用Marshalling方法到对应的XML。

我不明白如何使用 ObjectMapper 逐一读取事件并将其分配给相应的 Java 类。

以下是我的 JSON 文件的简单版本:(这是一个示例 JSON,我的原始 JSON 非常复杂)

{
   "@context":"https://context.org/context.jsonld",
   "isA":"SchoolManagement",
   "format":"application/ld+json",
   "schemaVersion":"2.0",
   "creationDate":"2021-04-21T10:10:09+00:00",
   "body":{
      "members":[
         {
            "isA":"student",
            "name":"ABCS",
            "class":10,
            "coaching":[
              "XSJSJ",
              "IIIRIRI"
            ],
            "dob":"1995-04-21T10:10:09+00:00"
         },
         {
            "isA":"teacher",
            "name":"ABCS",
            "department":"computer science",
            "school":{
              "name":"ABCD School"
            },
            "dob":"1995-04-21T10:10:09+00:00"
         },
         {
            "isA":"boardMember",
            "name":"ABCS",
            "board":"schoolboard",
            "dob":"1995-04-21T10:10:09+00:00"
         }
      ]
   }
}

我想一一读取“members”数组中的事件,判断是不是“student”、“teacher”等,然后分配给对应的class。

public class Main {

  public static void main(String[] args) throws JsonParseException,
  JsonMappingException,
  IOException,
  JAXBException {

    final ObjectMapper objectMapper = new ObjectMapper();

    // Accept the Null values for some fields
    objectMapper.setSerializationInclusion(Include.NON_NULL);

    // If any unknown properties found then do not fail
    objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

    //Here I want to read the element within an array 
    Student event = objectMapper.readValue(Main.class.getResourceAsStream("/events.json"), Student.class);
    System.out.println(event);

  }

}

【问题讨论】:

    标签: java json jackson objectmapper jackson2


    【解决方案1】:

    我会告诉你如何读取 JSON 文件并获取每个键的值,如何将其放入 XML 文件将掌握在你手中。

    1为您的 JSON 文件创建任意数量的 POJO(您可以在此处自动生成它:https://www.jsonschema2pojo.org/

    2代码:

        ObjectMapper objectMapper = new ObjectMapper();
                School school = new School();
                File file = new File("school.json");
                
                //With this you map the JSON file and get the data
                try {
                    school = objectMapper.readValue(file, School.class);
                    
                    String JSONOutputCustomer = objectMapper.writeValueAsString(school.getBody());
                    System.out.println(JSONOutputCustomer);
                    
                } catch (IOException e) {
                    e.printStackTrace();
                }
                /*With this you list the info inside of the key Body.
    I just did it with body, but you can do it with any key you want, as for example Member, you can list only the information of just one member insted all of them doing the same as the example below*/
    
                List<Body> bodyList = new ArrayList<Body>();
                
                for(Body values : bodyList) {
                    System.out.println(values.getMembers());
                }
    

    现在您知道如何获取每个键的值了。

    注意:我没有放 POJO 类,因为它们是 4 并且它的代码太多,你可以从我上面留下的链接中获得

    注2:别怪我拼写错误,我还在学英语T_T

    示例 2

    ObjectMapper objectMapper = new ObjectMapper();
    Member member = new Member();
            File file = new File("school.json");
    
    try {
                member = objectMapper.readValue(file, Member.class);
                
                String JSONOutputCustomer = objectMapper.writeValueAsString(member);
                System.out.println(JSONOutputCustomer);
            } catch (IOException e) {
                e.printStackTrace();
            }
    

    【讨论】:

    • 非常感谢您的回复。我明白你在这里想要做什么。但是通过这种方式,我们将整个内容加载到 school 对象中,对吧?此外,我们的bodyList 将包含我们稍后要遍历的完整列表。这可能会妨碍记忆我觉得这就是我试图逐个读取事件的原因,我首先喜欢从文件中只读student 然后读取teacherJsonParser 这样做但它读取行通过我必须再次映射到我的 Java 类和对象的行,所以我正在寻找可以结合两者最好的东西(ObjectMapperJsonParser
    • 你是对的,在这种情况下。我将向您展示其他情况,其中我们只阅读了会员。让我再回答一个
    • List 或 List 不重要,重要的是 objectMapper 和你用它做什么
    • @BATMAN_2008 那里,我已经修改了答案,告诉我这是否是你要找的,另外,我是 stackoverflow 的新手,我不知道如何让你知道我已经修改了答案与否,所以我在此评论中提到了您,让我们看看这是否有效 XD
    • 您好,非常感谢您的所有努力。是的,我正在研究答案并尝试对其进行修改,以便它可以与我的应用程序一起使用。我会让你知道这是否有效,否则我们可以找出一些东西。如果它成功了,那么你的答案旁边会有一个绿色的复选标记:) 再次感谢,祝你有美好的一天。
    【解决方案2】:

    基本上有三种使用 JACKSON2 解析 JSON 的方法,难度各不相同。

    1. ObjectMapper (mapper.readValue()):需要编写的代码更少——应该使用简单的数据绑定,
    2. ObjectMapper(树模型):中等代码 - 应该用于复杂的 JSON
    3. JsonParser(流模型):更多代码 - 需要终极性能时应使用。

    您正在寻找树模型。它结合了JSONParser 的灵活性和ObjectMapper 的易用性。试试下面的ObjectMapper

    //create Object Node using Tree model
    ObjectNode event = objectMapper.readTree("/events.json");
    
    //Now access the Json One by One as you like
    JsonNode memberNode = json.get("body").get("Members");
    

    There is Nice Mkyong tutorial for the Tree Model

    阅读更多: JACKSON2 Offical documentation

    【讨论】:

      猜你喜欢
      • 2020-10-18
      • 2012-03-03
      • 2014-05-24
      • 1970-01-01
      • 1970-01-01
      • 2016-11-03
      • 1970-01-01
      • 2011-03-31
      • 1970-01-01
      相关资源
      最近更新 更多