Last active
March 14, 2021 05:14
-
-
Save klausbrunner/9915362 to your computer and use it in GitHub Desktop.
Incrementally binding JSON objects in an array (list) using Jackson.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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