简体   繁体   中英

Parsing JSON into Jackson using a stream/object approach

I have a JSON file which can have multiple types.

For example:

{
    "dog": {
        "owner" : "John Smith",
        "name" : "Rex",
        "toys" : {
            "chewtoy" : "5",
            "bone" : "1"
        }
    },
    "person": {
        "name" : "John Doe",
        "address" : "23 Somewhere Lane"
    }
    // Further examples of dogs and people, and a few other types.
}

I want to parse these into objects. ie. I want to create a Dog object with owner/name/toys attributes, and person with name/address attributes, and use Jackson to read through and create objects out of them.

The ordering matters - I need to know that Rex came before John Doe, for example. I would prefer to do with a stream like approach (ie. read and parse Rex into the Dog object, do something with it, then discard it, then move onto to John Doe). So I need a stream based approach.

I can't figure out how to use both the stream reading API (to go through in order) and the ObjectMapper interface (in order to create Java objects out of JSON) to accomplish this.

To do this, you need to use an object mapper with your factory

import org.codehaus.jackson.JsonFactory;
import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.map.ObjectMapper;
...
private static ObjectMapper mapper = new ObjectMapper();
private static JsonFactory factory = mapper.getJsonFactory();

Then create a parser for the input.

JsonParser parser = factory.createJsonParser(in);

Now you can mix calls to parser.nextToken() and calls to parser.readValueAs(Class c) . Here is an example that gets the classes from a map:

Map<String, Class<?>> classMap = new HashMap<String, Class<?>>();
classMap.put("dog", Dog.class);
classMap.put("person", Person.class);

InputStream in = null;
JsonParser parser = null;
List<Object> results = new ArrayList<Object>();
try {
  in = this.getClass().getResourceAsStream("input.json");
  parser = factory.createJsonParser(in);
  parser.nextToken();// JsonToken.START_OBJECT
  JsonToken token = null;
  while( (token = parser.nextToken()) == JsonToken.FIELD_NAME ) {
    String name = parser.getText();
    parser.nextToken(); // JsonToken.START_OBJECT
    results.add(parser.readValueAs(classMap.get(name)));
  }
  // ASSERT: token = JsonToken.END_OBJECT
}
finally {
  IOUtils.closeQuietly(in);
  try {
    parser.close();
  }
  catch( Exception e ) {}
}

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