简体   繁体   中英

How to clone `com.fasterxml.jackson.core.JsonParser`

I need to parse the same json stream twice, one time to identify say the length of array in the json stream, and next to parse the entities. However, there is only a single instance of JsonParser to start with. Is there a way I can clone this or create a copy of this because once the instance is used to parse, it can't be reused for re-parsing the same json stream obviously. Thanks in advance.

Example:


   static class ResultEntitiesContainer {
     List<ResultEntity> resultEntities;
     // getter and setters available
   }

    void parseEntities(JsonParser parser) {
      // Need to extract number of entities. 
      int count=0;
      ObjectMapper om = new ObjectMapper();
      JsonNode node = om.readTree(parser);
      node = node.get("resultEntities");
      if (node.isArray()) {
        count = node.size();
      }

      // Need to parse the entities in the json node
      ResultEntitiesContainer rec = om.readValue(parser, ResultEntitiesContainer.class);

    }

This answer aims to address the question of cloning the JsonParser assuming it is required.

com.fasterxml.jackson.core.JsonParser is a public abstract class and it does not provide a clone or similar method. An abstract class may be extended by different implementations that the author of JsonParser.java has no control of. Similarly it is not safe to clone a JsonParser as an argument of void parseEntities(JsonParser parser); because the author of parseEntities cannot be sure which implementation is used and whether it can be cloned.

However if you (as the author of parseEntities ) do have control over the used implementations, then it is safe to clone the known implementations (assuming this is possible). So if you do know which specific implementation (or implementations) of JsonParser your class will be using, you can try and clone specifically these known implementations. Eg add and implemented one or more methods (as needed) like:

void parseEntities(MyJsonParser parser);

void parseEntities(MyOtherJsonParser parser);

Then it is a question of cloning the specific implementations of JsonParser that are used. For instance assuming MyJsonParser supports cloning the following could be valid.

void parseEntities(MyJsonParser parser){

MyJsonParser clonedParser=parser.clone();//depends on implementation

...

}

As far as I can see, there is no need to parse twice. Just parse it once into an object of type ResultEntitiesContainer and count the elements in the list to get count . You could change method parseEntities as follows:

void parseEntities(JsonParser parser) {
   ObjectMapper om = new ObjectMapper();

   // Need to parse the entities in the json node
   ResultEntitiesContainer rec = om.readValue(parser, ResultEntitiesContainer.class);
   // Need to extract number of entities. 
   int count = rec.getResultEntities().size();   
}

Alternatively you can parse to object ResultEntitiesContainer from json node as follows:

ResultEntitiesContainer rec = om.treeToValue(node, ResultEntitiesContainer.class);

Remark:

  • Please double check if ResultEntitiesContainer should be static .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM