Parsing JSON into Jackson using a stream/object approach
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 ) {}
}
Anonymous Person
Updated on July 19, 2022Comments
-
Anonymous Person almost 2 years
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.
-
Anonymous Person over 11 yearsI think I see now. When I was trying to do that initially, I was struggling because I wouldn't know what object I was at ("dog" or "person"), but if the data is formatted as an array with the dog/person values as values in a "type" attribute, I'd be able to do this. Thanks everyone.
-
Manu Manjunath about 7 yearsA good answer. But, it would be great if you can rewrite your code snippet using latest Jackson library.