API de streaming de Jackson

API de streaming de Jackson

Se você tem alguns anos de experiência no ecossistema Java e está interessado em compartilhar essa experiência com a comunidade (e ser pago por seu trabalho, é claro), dê uma olhada em"Write for Us" page. Felicidades. Eugen

1. Overview

Neste artigo, veremos a API de streaming Jackson. Ele suporta leitura e gravação e, usando-o, podemos escrever analisadores JSON rápidos e de alto desempenho.

Por outro lado, é um pouco difícil de usar - todos os detalhes dos dados JSON precisam ser tratados explicitamente no código.

2. Dependência do Maven

Em primeiro lugar, precisamos adicionar uma dependência Maven aojackson-core:


    com.fasterxml.jackson.core
    jackson-core
    2.9.4

3. Escrevendo para JSON

Podemos escrever conteúdo JSON diretamente emOutputStream usando uma classeJsonGenerator. Primeiramente, precisamos criar a instância desse objeto:

ByteArrayOutputStream stream = new ByteArrayOutputStream();
JsonFactory jfactory = new JsonFactory();
JsonGenerator jGenerator = jfactory
  .createGenerator(stream, JsonEncoding.UTF8);

Em seguida, digamos que queremos escrever um JSON com a seguinte estrutura:

{
   "name":"Tom",
   "age":25,
   "address":[
      "Poland",
      "5th avenue"
   ]
}

Podemos usar uma instância deJsonGenerator para escrever campos específicos diretamente para oOutputStream:

jGenerator.writeStartObject();
jGenerator.writeStringField("name", "Tom");
jGenerator.writeNumberField("age", 25);
jGenerator.writeFieldName("address");
jGenerator.writeStartArray();
jGenerator.writeString("Poland");
jGenerator.writeString("5th avenue");
jGenerator.writeEndArray();
jGenerator.writeEndObject();
jGenerator.close();

Para verificar se o JSON adequado foi criado, podemos criar um objetoString com o objeto JSON nele:

String json = new String(stream.toByteArray(), "UTF-8");
assertEquals(
  json,
  "{\"name\":\"Tom\",\"age\":25,\"address\":[\"Poland\",\"5th avenue\"]}");

4. Analisando JSON

Quando obtemos JSONString como entrada e queremos extrair campos específicos dele, uma classeJsonParser pode ser usada:

String json
  = "{\"name\":\"Tom\",\"age\":25,\"address\":[\"Poland\",\"5th avenue\"]}";
JsonFactory jfactory = new JsonFactory();
JsonParser jParser = jfactory.createParser(json);

String parsedName = null;
Integer parsedAge = null;
List addresses = new LinkedList<>();

Queremos obter os camposparsedName, parsedAge, and addresses do JSON de entrada. Para conseguir isso, precisamos lidar com a lógica de análise de baixo nível e implementá-la:

while (jParser.nextToken() != JsonToken.END_OBJECT) {
    String fieldname = jParser.getCurrentName();
    if ("name".equals(fieldname)) {
        jParser.nextToken();
        parsedName = jParser.getText();
    }

    if ("age".equals(fieldname)) {
        jParser.nextToken();
        parsedAge = jParser.getIntValue();
    }

    if ("address".equals(fieldname)) {
        jParser.nextToken();
        while (jParser.nextToken() != JsonToken.END_ARRAY) {
            addresses.add(jParser.getText());
        }
    }
}
jParser.close();

Dependendo do nome do campo, estamos extraindo-o e atribuindo-o a um campo apropriado. Após analisar o documento, todos os campos devem ter dados corretos:

assertEquals(parsedName, "Tom");
assertEquals(parsedAge, (Integer) 25);
assertEquals(addresses, Arrays.asList("Poland", "5th avenue"));

5. Extraindo partes JSON

Às vezes, quando analisamos um documento JSON, estamos interessados ​​em apenas um campo específico.

Idealmente, nessas situações, queremos analisar apenas o início do documento e, uma vez encontrado o campo necessário, podemos interromper o processamento.

Digamos que estejamos interessados ​​apenas no campoage do JSON de entrada. Nesse caso, podemos implementar a lógica de análise para interromper a análise assim que o campo necessário for encontrado:

while (jParser.nextToken() != JsonToken.END_OBJECT) {
    String fieldname = jParser.getCurrentName();

    if ("age".equals(fieldname)) {
        jParser.nextToken();
        parsedAge = jParser.getIntValue();
        return;
    }

}
jParser.close();

Após o processamento, o único campoparsedAge terá um valor:

assertNull(parsedName);
assertEquals(parsedAge, (Integer) 25);
assertTrue(addresses.isEmpty());

Graças a isso, a análise do documento JSON será muito mais rápida, porque não precisamos ler o documento inteiro, mas apenas uma pequena parte dele.

6. Conclusão

Neste artigo rápido, veremos como podemos aproveitar a API de processamento de fluxo de Jackson.

A implementação de todos esses exemplos e trechos de código pode ser encontradaover on GitHub - este é um projeto Maven, portanto, deve ser fácil de importar e executar como está.