JSON Splitter
El JSON Splitter proporcionado por IPF está implementado usando la biblioteca Actson JSON streaming parser. Toma una component hierarchy que define la estructura de los elementos JSON a dividir.
Cabe señalar que los datos de los elementos JSON generados estarán compactados. Es decir, cualquier espacio en blanco extra en el documento original se eliminará de los componentes publicados. Las versiones futuras pueden incluir configuración para preservar el formato de origen.
Maven Dependency
Para usar el JSON splitter, se debe proporcionar la siguiente dependencia, con una versión que coincida con ipf-debulker-core para asegurar la compatibilidad.
<dependency>
<groupId>com.iconsolutions.ipf.debulk</groupId>
<artifactId>ipf-debulker-json-splitter</artifactId>
<version>${ipf-debulker-core.version}</version>
</dependency>
Ejemplo de uso
Imagina que queremos procesar archivos JSON potencialmente grandes que contienen datos sobre libros en una biblioteca y dividirlo en partes más pequeñas, para que puedan ser usados por algún sistema downstream.
El archivo de ejemplo es pequeño con fines de demostración, pero podría contener un gran número de elementos de libros.
example.json
{
"name": "Library of Alexandria",
"meta": {
"bookCount": 2,
"authorCount": 2,
"mixedValueList": [
1, {}, 2.0, [], true, false, null, {}, [], {}
],
"listOfList": [[],[],[]]
},
"books": [
{
"title": "Clean Code",
"author": "Martin, Robert",
"price": 39.99,
"chapters": [
{
"name": "Clean Code",
"startPage": 1
},
{
"name": "Meaningful Names",
"startPage": 17
}
]
},
{
"title": "Effective Java",
"author": "Bloch, Joshua",
"price": 55.00,
"chapters": [
{
"name": "Introduction",
"startPage": 1,
"meta": {
"x": "wow"
}
},
{
"name": "Creating and Destroying Objects",
"startPage": 5
}
]
}
]
}
Dado nuestro JSON de ejemplo, podríamos decidir dividirlo usando la siguiente jerarquía.
library
└── books
└── chapters
Con estos prerrequisitos fuera del camino, escribamos el programa. Ten en cuenta que este ejemplo usa Project Reactor para convertir Flow.Publisher de Java 9 a un Flux para facilitar la suscripción a los datos, pero podría reemplazarse por otra biblioteca reactiva compatible con las bibliotecas reactivas de Java 9, como Akka Streams o RxJava.
ActorSystem system = ActorSystem.create();
AkkaJsonSplitter splitter = new AkkaJsonSplitter(system);
InputStream stream = getClass().getClassLoader().getResourceAsStream("example.json");
ComponentHierarchy root = ComponentHierarchy.root("$");
ComponentHierarchy book = root.addChild("books[]");
book.addChild("chapters[]");
Flow.Publisher<DebulkComponent> publisher = splitter.split(stream, root);
Flux<DebulkComponent> flux = JdkFlowAdapter.flowPublisherToFlux(publisher);
List<DebulkComponent> components = flux.collectList().blockOptional().orElseThrow();
System.out.println();
components.stream()
.map(DebulkComponent::getContent)
.forEach(System.out::println);
Al ejecutar este código debería imprimirse en la consola una serie de componentes extraídos.
output
{"name":"Clean Code","startPage":1}
{"name":"Meaningful Names","startPage":17}
{"title":"Clean Code","author":"Martin, Robert","price":39.99}
{"name":"Introduction","startPage":1,"meta":{"x":"wow"}}
{"name":"Creating and Destroying Objects","startPage":5}
{"title":"Effective Java","author":"Bloch, Joshua","price":55.0}
{"name":"Library of Alexandria","meta":{"bookCount":2,"authorCount":2,"mixedValueList":[1,{},2.0,[],true,false,null,{},[],{}],"listOfList":[[],[],[]]}}