1

I am using Jackson 2.2 to read a very large JSON string into a Java object. Using ObjectMapper, I read everything into the memory and transform the JSON string to object. This is all happening in memory, so the entire JSON string is loaded into the memory and transformed into the object.

If there a more memory efficient way of doing it? i.e. without loading the entire JSON string into the memory, I should still be able to load the object.

StaxMan
  • 113,358
  • 34
  • 211
  • 239
Abhi
  • 129
  • 6

1 Answers1

0

Yes, you typically use so-called "streaming" API to iterate over JSON tokens; and once positioned over first token of the value you want (START_OBJECT for JSON Objects), use data-binding API, passing reader/parser for it to use. Details of this depend on library. I know that at least following support this mode of operation:

  • Jackson
  • Gson
  • Genson

For Jackson, basic Streaming API usage is talked about here (for example); but one thing that does not show is how to bind objects once you are positioned at the right place. So assuming JSON like:

{ "comment" : "...",
  "values" : [
     { ... value object 1 ... },
     { ... value object 2. ... }
  ]
}

you could do:

ObjectMapper mapper = new ObjectMapper();
JsonParser jp = mapper.getFactory().createJsonParser(jsonInput);
jp.nextToken(); // will return START_OBJECT, may want to verify
while (jp.nextValue() != null) { // 'nextValue' skips FIELD_NAME token, if any
  String fieldName = jp.getCurrentName();
  if ("values".equals(fieldName)) {
    // yes, should now point to START_ARRAY
    while (jp.nextToken() == JsonToken.START_OBJECT) {
      ValueObject v = mapper.readValue(jp, ValueObject.class);
      // process individual value in whatever way to you want to...
    }
  } else if ("comment".equals(fieldName)) {
     // handle comment?
  } // may use another else to catch unknown fields, if any
}
jp.close();

and that should let you only bind one object at a time.

StaxMan
  • 113,358
  • 34
  • 211
  • 239