Потоковое API Джексона

Потоковое API Джексона

Если у вас есть несколько лет опыта в экосистеме Java, и вы заинтересованы в том, чтобы поделиться этим опытом с сообществом (и, конечно, получать деньги за свою работу), взгляните на"Write for Us" page. Приветствия. Eugen

1. Overviewс

В этой статье мы рассмотрим API потоковой передачи Jackson. Он поддерживает как чтение, так и запись, и с его помощью мы можем создавать высокопроизводительные и быстрые парсеры JSON.

С другой стороны, это немного сложно использовать - каждая деталь данных JSON должна быть явно обработана в коде.

2. Maven Dependency

Во-первых, нам нужно добавить зависимость Maven кjackson-core:


    com.fasterxml.jackson.core
    jackson-core
    2.9.4

3. Запись в JSON

Мы можем записать содержимое JSON непосредственно вOutputStream, используя классJsonGenerator. Во-первых, нам нужно создать экземпляр этого объекта:

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

Далее, допустим, мы хотим написать JSON со следующей структурой:

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

Мы можем использовать экземплярJsonGenerator для записи определенных полей непосредственно вOutputStream:

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();

Чтобы проверить, был ли создан правильный JSON, мы можем создать объектString с объектом JSON в нем:

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

4. Разбор JSON

Когда мы получаем JSONString в качестве входных данных и хотим извлечь из него определенные поля, можно использовать классJsonParser:

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<>();

Мы хотим получить поляparsedName, parsedAge, and addresses из входного JSON. Чтобы достичь этого, нам нужно обработать низкоуровневую логику синтаксического анализа и реализовать ее самостоятельно:

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();

В зависимости от имени поля мы извлекаем его и присваиваем правильному полю. После анализа документа все поля должны иметь правильные данные:

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

5. Извлечение частей JSON

Иногда, когда мы анализируем документ JSON, нас интересует только одно конкретное поле.

В идеале в этих ситуациях мы хотим проанализировать только начало документа, и как только будет найдено необходимое поле, мы можем прервать обработку.

Допустим, нас интересует только полеage входного JSON. В этом случае мы можем реализовать логику синтаксического анализа, чтобы прекратить синтаксический анализ, когда нужное поле найдено:

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

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

}
jParser.close();

После обработки единственное полеparsedAge будет иметь значение:

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

Благодаря этому синтаксический анализ документа JSON будет намного быстрее, поскольку нам не нужно читать весь документ, а только его небольшую часть.

6. Заключение

В этой быстрой статье мы рассмотрим, как можно использовать Stream Processing API от Jackson.

Реализацию всех этих примеров и фрагментов кода можно найти вover on GitHub - это проект Maven, поэтому его должно быть легко импортировать и запускать как есть.