是否有可能使用 Jackson JsonParser 在 JSONObject/JsonNode 中一次存储单个事件信息

Is there a possibility to store the single event information at a time in a JSONObject/JsonNode using the Jackson JsonParser

我正在尝试使用 Jackson JsonParser 从大型 JSON 文件中逐个读取事件。我想将每个事件临时存储在一个对象中,例如 JsonObject 或我以后想用于进一步处理的任何其他对象。

我之前正在逐一阅读 JSON 事件并将它们存储到我自己的自定义上下文中:Old Post for JACKSON JsonParser Context 工作正常。但是,我想将它们一个一个地存储到 jsonObject 或其他一些对象中,而不是上下文。

以下是我的示例 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"
         }
      ]
   }
}

一次我只想在我的JsonObject.

中存储一个member,例如studentteacher

以下是我目前的代码: 将每个事件存储在一个对象中的最佳方法是什么,我以后可以将其用于某些处理。 然后再次清除该对象并将其用于下一个事件?

public class Main {

    private JSONObject eventInfo;
    private final String[] eventTypes = new String[] { "student", "teacher", "boardMember" };

    public static void main(String[] args) throws JsonParseException, JsonMappingException, IOException, JAXBException, URISyntaxException {
        // Get the JSON Factory and parser Object
        JsonFactory jsonFactory = new JsonFactory();
        JsonParser jsonParser = jsonFactory.createParser(new File(Main.class.getClassLoader().getResource("inputJson.json").toURI()));
        JsonToken current = jsonParser.nextToken();

        // Check the first element is Object
        if (current != JsonToken.START_OBJECT) {
            throw new IllegalStateException("Expected content to be an array");
        }

        // Loop until the start of the EPCIS EventList array
        while (jsonParser.nextToken() != JsonToken.START_ARRAY) {
            System.out.println(jsonParser.getCurrentToken() + " --- " + jsonParser.getCurrentName());
        }

        // Goto the next token
        jsonParser.nextToken();

        // Call the method to loop until the end of the events file
        eventTraverser(jsonParser);
    }

    // Method which will traverse through the eventList and read event one-by-one
    private static void eventTraverser(JsonParser jsonParser) throws IOException {

        // Loop until the end of the EPCIS events file
        while (jsonParser.nextToken() != JsonToken.END_OBJECT) {
            
            //Is there a possibility to store the complete object directly in an JSON Object or I need to again go through every token to see if is array and handle it accordingly as mentioned in my previous POST.
            
        }
    }
}

在尝试了一些东西之后,我能够让它正常工作。我正在 post 整理整个代码,因为它可能对将来的某个人有用,因为我知道找到合适的工作代码示例是多么令人沮丧:

public class Main
{
  public void xmlConverter (InputStream jsonStream) throws IOException,JAXBException, XMLStreamException
  {
    // jsonStream is the input JSOn which is normally passed by reading the JSON file
    
    // Get the JSON Factory and parser Object
    final JsonFactory jsonFactory = new JsonFactory ();
    final JsonParser jsonParser = jsonFactory.createParser (jsonStream);
    final ObjectMapper objectMapper = new ObjectMapper ();

    //To read the duplicate keys if there are any key duplicate json
    final SimpleModule module = new SimpleModule ();
      module.addDeserializer (JsonNode.class, new JsonNodeDupeFieldHandlingDeserializer ());
      objectMapper.registerModule (module);
      jsonParser.setCodec (objectMapper);

    // Check the first element is Object if not then invalid JSON throw error
    if (jsonParser.nextToken () != JsonToken.START_OBJECT)
      {
    throw new IllegalStateException ("Expected content to be an array");
      }

    while (!jsonParser.getText ().equals ("members"))
      {
    //Skipping the elements till members key
    // if you want you can do some process here
    // I am skipping for now
      }

    // Goto the next token
    jsonParser.nextToken ();

    while (jsonParser.nextToken () != JsonToken.END_ARRAY)
      {
    final JsonNode jsonNode = jsonParser.readValueAsTree ();

    //Check if the JsonNode is valid if not then exit the process
    if (jsonNode == null || jsonNode.isNull ())
      {
        System.out.println ("End Of File");
        break;
      }

    // Get the eventType
    final String eventType = jsonNode.get ("isA").asText ();

    // Based on eventType call different type of class
    switch (eventType)
      {
      case "student":
        final Student studentInfo =
          objectMapper.treeToValue (jsonNode, Student.class);
        //I was calling the JAXB Method as I was doing the JSON to XML Conversion
        xmlCreator (studentInfo, Student.class);
        break;
      case "teacher":
        final Teacher teacherInfo =
          objectMapper.treeToValue (jsonNode, Teacher.class);
        xmlCreator (teacherInfo, Teacher.class);
        break;
      }
      }

  }

  //Method to create the XML using the JAXB
  private void xmlCreator (Object eventInfo,
               Class eventType) throws JAXBException
  {
    private final StringWriter sw = new StringWriter ();

    // Create JAXB Context object
    JAXBContext context = JAXBContext.newInstance (eventType);

    // Create Marshaller object from JAXBContext
    Marshaller marshaller = context.createMarshaller ();

    // Print formatted XML
      marshaller.setProperty (Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);

    // Do not add the <xml> version tag
      marshaller.setProperty (Marshaller.JAXB_FRAGMENT, Boolean.TRUE);

    // XmlSupportExtension is an interface that every class such as Student Teacher implements
    // xmlSupport is a method in XmlSupportExtension which has been implemented in all classes

    // Create the XML based on type of incoming event type and store in SW
      marshaller.marshal (((XmlSupportExtension) eventInfo).xmlSupport (),
              sw);

    // Add each event within the List
      eventsList.add (sw.toString ());

    // Clear the StringWritter for next event
      sw.getBuffer ().setLength (0);

  }
}

这是覆盖 JACKSON class 的 class。 如果您的 Json 有重复的 JSON 键,则可以使用它。如果需要,请按照此 post 进行完整说明。如果你不需要那么跳过这部分并从上面的 class 中删除代码 module 的部分:


@JsonDeserialize(using = JsonNodeDupeFieldHandlingDeserializer.class)
public class JsonNodeDupeFieldHandlingDeserializer extends JsonNodeDeserializer {

  @Override
  protected void _handleDuplicateField(JsonParser p, DeserializationContext ctxt, JsonNodeFactory nodeFactory, String fieldName,
      ObjectNode objectNode, JsonNode oldValue, JsonNode newValue) {

    ArrayNode asArrayValue = null;

    if (oldValue.isArray()) {
      asArrayValue = (ArrayNode) oldValue;
    } else {
      asArrayValue = nodeFactory.arrayNode();
      asArrayValue.add(oldValue);
    }
    asArrayValue.add(newValue);
    objectNode.set(fieldName, asArrayValue);
  }

}