Incrementally binding JSON objects in an array (list) using Jackson.
package tv.xrm.test; | |
import com.fasterxml.jackson.core.type.TypeReference; | |
import com.fasterxml.jackson.databind.ObjectMapper; | |
import java.util.*; | |
public class JacksonStreamingBindingTest { | |
public static void main(String[] args) throws Exception { | |
final String jsonList = generateListOfJsonObjects(); | |
final TypeReference<Map<String, String>> typeRef = new TypeReference<Map<String, String>>() { | |
}; | |
/* This works for a "wrapped" sequence of objects, i.e. a JSON array. Using | |
ObjectMapper.readValues(JsonParser, ...) will NOT work for an array, as | |
that assumes a non-wrapped sequence of values. See source of MappingIterator. | |
*/ | |
Iterator<Map<String, String>> it = new ObjectMapper().reader(typeRef).readValues(jsonList); | |
while (it.hasNext()) { | |
Map<String, String> map = it.next(); | |
System.out.println(map); | |
} | |
} | |
/** | |
* A quick & dirty method to generate a long JSON list of somewhat random objects. | |
*/ | |
private static String generateListOfJsonObjects() throws Exception { | |
final int length = 1000; | |
final Random r = new Random(); | |
List<Map<String, String>> result = new ArrayList<>(length); | |
for (int i = 0; i < length; i++) { | |
Map<String, String> map = new HashMap<>(); | |
for (int j = 0; j < 3; j++) { | |
map.put("key" + r.nextInt(), "value" + r.nextInt()); | |
} | |
result.add(map); | |
} | |
return (new ObjectMapper()).writeValueAsString(result); | |
} | |
} |
package tv.xrm.test; | |
import com.fasterxml.jackson.core.JsonParser; | |
import com.fasterxml.jackson.core.JsonToken; | |
import com.fasterxml.jackson.core.type.TypeReference; | |
import com.fasterxml.jackson.databind.ObjectMapper; | |
import java.io.IOException; | |
import java.util.*; | |
/** | |
* Just a test of "manually" mixing Jackson's streaming and data binding modes. This kind of approach works | |
* for any arbitrary JSON structure. | |
* | |
* @see com.fasterxml.jackson.databind.ObjectMapper#readValues(com.fasterxml.jackson.core.JsonParser, com.fasterxml.jackson.core.type.TypeReference) | |
* | |
*/ | |
public class JacksonStreamingBindingTest2 { | |
interface Processor<T> { | |
void process(T object); | |
} | |
public static void main(String[] args) throws Exception { | |
final String jsonList = generateListOfJsonObjects(); | |
JsonParser jp = new ObjectMapper().getFactory().createParser(jsonList); | |
final TypeReference<Map<String, String>> typeRef = new TypeReference<Map<String, String>>() { | |
}; | |
bindListElementsIteratively(jp, typeRef, new Processor<Map<String, String>>() { | |
@Override | |
public void process(Map<String, String> stringStringMap) { | |
System.out.println(stringStringMap); | |
} | |
}); | |
} | |
/** | |
* Parse list incrementally by binding each list element after the other, using a callback for processing. | |
*/ | |
private static <T> void bindListElementsIteratively(JsonParser jp, TypeReference<T> typeRef, Processor<T> func) throws IOException { | |
try { | |
if (jp.nextToken() != JsonToken.START_ARRAY) { | |
throw new IOException("expected data to start with an array"); | |
} | |
JsonToken current = jp.nextToken(); | |
while (current != null && current != JsonToken.END_ARRAY) { | |
if (current.isStructStart()) { | |
final T mapped = jp.readValueAs(typeRef); | |
func.process(mapped); | |
} | |
current = jp.nextToken(); | |
} | |
} finally { | |
jp.close(); | |
} | |
} | |
/** | |
* A quick & dirty method to generate a long JSON list of somewhat random objects. | |
*/ | |
private static String generateListOfJsonObjects() throws Exception { | |
final int length = 1000; | |
final Random r = new Random(); | |
List<Map<String, String>> result = new ArrayList<>(length); | |
for (int i = 0; i < length; i++) { | |
Map<String, String> map = new HashMap<>(); | |
for (int j = 0; j < 3; j++) { | |
map.put("key" + r.nextInt(), "value" + r.nextInt()); | |
} | |
result.add(map); | |
} | |
return (new ObjectMapper()).writeValueAsString(result); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment