1

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); } 
4
  • Can you give an example showing some code? Commented May 4, 2020 at 7:20
  • Provided an example. Here, I need to use the same parser instance, but parse the json stream twice. Commented May 4, 2020 at 9:06
  • how does ResultEntitiesContainer look like? can you count by iterating over a field of ResultEntitiesContainer? Commented May 4, 2020 at 9:26
  • It is just a container class, nothing special in it. Let me add that too. Commented May 4, 2020 at 9:28

2 Answers 2

1

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. E.g. 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

...

}

Sign up to request clarification or add additional context in comments.

Comments

0

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.

2 Comments

Sorry, unfortunately that is not the case. I tried to simplify the example here, so what you mentioned is right with respect to the example given. However, the real question is to be able to clone the JsonParser.
I edited my answer to the possiblility of parsing the json node to the object instead of the parser. Can you please check if this works for you?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.