Skip to main content

Command Palette

Search for a command to run...

Jakarta JSON Processing (JSON-P) en Quarkus: Manipulación Programática de JSON

Updated
3 min read

Introducción

Jakarta JSON Processing (JSON-P) proporciona APIs para crear, parsear, transformar y consultar JSON de forma programática. A diferencia de JSON-Binding, JSON-P te da control total sobre la estructura JSON.

¿Qué es JSON-Processing?

JSON-P ofrece dos APIs principales:

  1. Object Model API: Para manipular JSON como objetos (JsonObject, JsonArray)

  2. Streaming API: Para procesar JSON grande de forma eficiente (JsonParser, JsonGenerator)

Object Model API

Crear JsonObject

JsonObjectBuilder builder = Json.createObjectBuilder();
builder.add("name", "Superman")
       .add("powerLevel", 95)
       .add("isActive", true);

// Objeto anidado
JsonObjectBuilder locationBuilder = Json.createObjectBuilder();
locationBuilder.add("city", "Metropolis");
builder.add("location", locationBuilder);

// Array
JsonArrayBuilder abilitiesBuilder = Json.createArrayBuilder();
abilitiesBuilder.add("Super strength").add("Flight");
builder.add("abilities", abilitiesBuilder);

JsonObject hero = builder.build();

Crear JsonArray

JsonArrayBuilder arrayBuilder = Json.createArrayBuilder();

JsonObjectBuilder hero1 = Json.createObjectBuilder();
hero1.add("name", "Superman").add("powerLevel", 95);
arrayBuilder.add(hero1);

JsonObjectBuilder hero2 = Json.createObjectBuilder();
hero2.add("name", "Batman").add("powerLevel", 85);
arrayBuilder.add(hero2);

JsonArray heroes = arrayBuilder.build();

Parsear JSON

String jsonString = "{\"name\":\"Superman\",\"powerLevel\":95}";
JsonReader reader = Json.createReader(new StringReader(jsonString));
JsonObject jsonObject = reader.readObject();
reader.close();

Escribir con Formato

Map<String, Object> config = Map.of(JsonGenerator.PRETTY_PRINTING, true);
JsonWriterFactory factory = Json.createWriterFactory(config);
StringWriter writer = new StringWriter();
JsonWriter jsonWriter = factory.createWriter(writer);
jsonWriter.writeObject(jsonObject);
jsonWriter.close();
String formattedJson = writer.toString();

JsonPointer (RFC 6901) - Querying JSON

JsonPointer permite consultar valores específicos en JSON:

// Consultar un valor
JsonPointer pointer = Json.createPointer("/name");
JsonValue value = pointer.getValue(jsonObject);

// Agregar un valor
JsonPointer pointer = Json.createPointer("/newField");
JsonObject modified = pointer.add(jsonObject, Json.createValue("newValue"));

// Eliminar un valor
JsonPointer pointer = Json.createPointer("/fieldToRemove");
JsonObject modified = pointer.remove(jsonObject);

JsonPatch (RFC 6902) - Transformar JSON

JsonPatch permite transformar JSON usando operaciones estándar:

// Crear operaciones de patch
JsonArrayBuilder patchBuilder = Json.createArrayBuilder();

// Operación: reemplazar
JsonObjectBuilder replaceOp = Json.createObjectBuilder();
replaceOp.add("op", "replace")
         .add("path", "/powerLevel")
         .add("value", 98);
patchBuilder.add(replaceOp);

// Operación: agregar
JsonObjectBuilder addOp = Json.createObjectBuilder();
addOp.add("op", "add")
     .add("path", "/newField")
     .add("value", "newValue");
patchBuilder.add(addOp);

JsonArray patchOperations = patchBuilder.build();

// Aplicar patch
JsonPatch patch = Json.createPatch(patchOperations);
JsonObject transformed = patch.apply(original);

Streaming API

JsonParser - Parsear JSON Grande

JsonParser parser = Json.createParser(new StringReader(jsonString));

while (parser.hasNext()) {
    JsonParser.Event event = parser.next();

    switch (event) {
        case KEY_NAME:
            String key = parser.getString();
            break;
        case VALUE_STRING:
            String value = parser.getString();
            break;
        case VALUE_NUMBER:
            if (parser.isIntegralNumber()) {
                long number = parser.getLong();
            } else {
                BigDecimal decimal = parser.getBigDecimal();
            }
            break;
        // ... más eventos
    }
}
parser.close();

JsonGenerator - Generar JSON Grande

Map<String, Object> config = Map.of(JsonGenerator.PRETTY_PRINTING, true);
JsonGenerator generator = Json.createGeneratorFactory(config)
    .createGenerator(writer);

generator.writeStartObject()
         .write("name", "Superman")
         .write("powerLevel", 95)
         .writeStartObject("location")
             .write("city", "Metropolis")
         .writeEnd()
         .writeStartArray("abilities")
             .write("Super strength")
             .write("Flight")
         .writeEnd()
         .writeEnd();

generator.close();

Filtrar y Transformar

Filtrar JsonArray

JsonArrayBuilder filteredBuilder = Json.createArrayBuilder();

for (JsonValue heroValue : heroesArray) {
    if (heroValue.getValueType() == JsonValue.ValueType.OBJECT) {
        JsonObject hero = heroValue.asJsonObject();
        int powerLevel = hero.getInt("powerLevel", 0);

        if (powerLevel >= minPowerLevel) {
            filteredBuilder.add(hero);
        }
    }
}

JsonArray filtered = filteredBuilder.build();

Comparación: JSON-Processing vs JSON-Binding

CaracterísticaJSON-ProcessingJSON-Binding
PropósitoManipulación programáticaSerialización automática
APIJsonObject, JsonArrayAnotaciones en clases Java
UsoCuando necesitas control totalCuando trabajas con objetos Java
StreamingSí (JsonParser/Generator)No
QueryingSí (JsonPointer)No
TransformationsSí (JsonPatch)No

Ejemplo Completo

Nuestro demo muestra:

  • Creación de JsonObject y JsonArray programáticamente

  • Parsing de JSON strings

  • Escritura con formato

  • JsonPointer para consultar JSON

  • JsonPatch para transformar JSON

  • Streaming API para JSON grande

  • Filtrado y transformación

Ventajas en Quarkus

  1. Control Total: Manipulación completa de JSON

  2. Streaming: Eficiente para JSON grande

  3. Estándares: JsonPointer y JsonPatch son RFCs estándar

  4. Flexibilidad: Útil cuando JSON-Binding no es suficiente

Conclusión

JSON-Processing es perfecto cuando necesitas manipular JSON directamente o cuando JSON-Binding no cubre tus necesidades. Las APIs de streaming son especialmente útiles para procesar JSON grande.

Recursos

More from this blog

JoeDayz

52 posts

Community Guy | Java Champion | AWS Architect | Software Architect