8

I've been using both JSONObject and JSONReader, but ideally I'm looking for a hybrid :)

In particular, given a stream of JSON objects, part of arbitrarily long JSON array, is there a helper/library that yields "JSONObject" at a time, iterator style, instead of reading everything in or having to parse out individual primitive fields (JsonReader)?

Example of hypothetical API:

JsonReader reader = new JsonReader(new InputStreamReader(in, "UTF-8"));

reader.beginArray();
while (reader.hasNext()) 
{
  JSONObject obj = reader.readObject();
  // do something with 'obj'
}
reader.endArray();

Above, calling readObject parses some complex JSON sub-tree and returns it as JSONObject.

Slawomir
  • 3,194
  • 1
  • 30
  • 36
  • possible duplicate of [What’s the best way to load a JSONObject from a json text file?](http://stackoverflow.com/questions/7463414/what-s-the-best-way-to-load-a-jsonobject-from-a-json-text-file) – mawburn Jul 31 '14 at 17:00
  • 1
    Not applicable. The JSONArray may be too big to store at once in memory. I want to read any-length-array by JSONObject-at-a-time. The API would ideally block in readObject until a JSONObject-element of the array can be returned. – Slawomir Jul 31 '14 at 17:25
  • 2
    There are a few incremental JSON readers (similar to the incremental XML readers which are more popular), but they're pretty rare and awkward to use. The natural way to deal with JSON is as a tree, but you can't do that very well if the left side of the tree is still buried in the ground. – Hot Licks Jul 31 '14 at 18:02
  • Did you ever resolve this? I have to do the same but can't find any library that handles this for me. – Havnar Aug 07 '18 at 12:29
  • Sorry, I wrote my own stack on top of the Reader. – Slawomir Aug 07 '18 at 18:22

1 Answers1

9

There's the javax.json.JSONParser.

An example that prints out a JSON:

import javax.json.Json;
import javax.json.stream.JsonParser;
...
JsonParser parser = Json.createParser(new StringReader(jsonData));
while (parser.hasNext()) {
   JsonParser.Event event = parser.next();
   switch(event) {
      case START_ARRAY:
      case END_ARRAY:
      case START_OBJECT:
      case END_OBJECT:
      case VALUE_FALSE:
      case VALUE_NULL:
      case VALUE_TRUE:
         System.out.println(event.toString());
         break;
      case KEY_NAME:
         System.out.print(event.toString() + " " +
                          parser.getString() + " - ");
         break;
      case VALUE_STRING:
      case VALUE_NUMBER:
         System.out.println(event.toString() + " " +
                            parser.getString());
         break;
   }
}

from The Java EE Tutorial 19.4.1 Reading JSON Data Using a Parser. It's part of the JavaEE 7 API but a standalone jar can be gotten from https://jsonp.java.net/download.html.

Ludovic Kuty
  • 4,868
  • 3
  • 28
  • 42
vandale
  • 3,600
  • 3
  • 22
  • 39
  • 1
    Part of Apache now. See [Jakarta JSON Processing](https://projects.eclipse.org/projects/ee4j.jsonp) and on Github at https://github.com/eclipse-ee4j/jsonp. – Ludovic Kuty Apr 18 '20 at 07:31
  • 1
    Found the JARs for 1.1.4: [API](https://repo1.maven.org/maven2/javax/json/javax.json-api/1.1.4/) and [implementation](https://repo1.maven.org/maven2/org/glassfish/javax.json/1.1.4/). – Ludovic Kuty Apr 19 '20 at 10:11
  • Thanks @LudovicKuty. To add as maven/gradle dependency: https://mvnrepository.com/artifact/org.glassfish/javax.json – Ari Singh Sep 18 '21 at 00:18
  • what about changing the value? Do we have to overwrite the JSON while reading each token? – ʀᴀʜɪʟ Mar 31 '22 at 08:30
  • @ʀᴀʜɪʟ unfortunately` javax.json.JSONParser` provides only read-only access. you'll have to use a different api if you need to modify the value. you may be able to simply construct the output stream by consuming every event, but that might be error prone. – vandale Apr 20 '22 at 04:57