Рубрики
Без рубрики

Введение в Джексон ОбъектМаппер

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

Автор оригинала: baeldung.

1. Обзор

Этот учебник фокусируется на понимании Джексона ОбъектМаппер класс и как сериализировать java-объекты в JSON и дезериализировать строку JSON в java-объекты.

Чтобы узнать больше о библиотеке Джексона в целом, Джексон Tutorial является хорошим местом для начала.

Дальнейшее чтение:

Наследование с Джексоном

Джексон JSON Просмотров

Джексон — пользовательский сериализатор

2. Зависимости

Давайте сначала добавим следующие зависимости к пом.xml :


    com.fasterxml.jackson.core
    jackson-databind
    2.11.1

Эта зависимость также будет временно добавить следующие библиотеки к классу:

  1. Джексон-аннотации
  2. Джексон-ядро

Всегда используйте последние версии из центрального репозитория Maven для Джексон-databind .

3. Чтение и написание с помощью ObjectMapper

Начнем с основных операций чтения и записи.

Простая readValue API ОбъектМаппер является хорошей точкой входа. Мы можем использовать его для разбора или deserialize содержимого JSON в Java-объект.

Кроме того, на письменной стороне, мы можем использовать writeValue API для сериализации любого объекта Java в качестве вывода JSON.

Мы будем использовать следующие Автомобильные класс с двумя полями в качестве объекта для сериализации или дезериализации на протяжении всей этой статьи:

public class Car {

    private String color;
    private String type;

    // standard getters setters
}

3.1. Объект Java для JSON

Давайте посмотрим первый пример сериализации объекта Java в JSON с помощью writeValue метод ОбъектМаппер класс:

ObjectMapper objectMapper = new ObjectMapper();
Car car = new Car("yellow", "renault");
objectMapper.writeValue(new File("target/car.json"), car);

Выход вышеуказанного в файле будет:

{"color":"yellow","type":"renault"}

Методы writeValueAsString и writeValueAsBytes ОбъектМаппер класс генерирует JSON из объекта Java и возвращает сгенерированный JSON в качестве строки или в качестве массива карт:

String carAsString = objectMapper.writeValueAsString(car);

3.2. JSON к объекту Java

Ниже приведен простой пример преобразования строки JSON в java-объект с помощью ОбъектМаппер класс:

String json = "{ \"color\" : \"Black\", \"type\" : \"BMW\" }";
Car car = objectMapper.readValue(json, Car.class);	

readValue () функция также принимает другие формы ввода, такие как файл, содержащий строку JSON:

Car car = objectMapper.readValue(new File("src/test/resources/json_car.json"), Car.class);

или URL:

Car car = 
  objectMapper.readValue(new URL("file:src/test/resources/json_car.json"), Car.class);

3.3. JSON Джексон JsonNode

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

String json = "{ \"color\" : \"Black\", \"type\" : \"FIAT\" }";
JsonNode jsonNode = objectMapper.readTree(json);
String color = jsonNode.get("color").asText();
// Output: color -> Black

3.4. Создание списка Java из строки JSON Array

Мы можем разобрать JSON в виде массива в списке объектов Java с помощью ТипРеференс :

String jsonCarArray = 
  "[{ \"color\" : \"Black\", \"type\" : \"BMW\" }, { \"color\" : \"Red\", \"type\" : \"FIAT\" }]";
List listCar = objectMapper.readValue(jsonCarArray, new TypeReference>(){});

3.5. Создание Java-карты из строки JSON

Аналогичным образом, мы можем разобрать JSON на Java- Карта :

String json = "{ \"color\" : \"Black\", \"type\" : \"BMW\" }";
Map map 
  = objectMapper.readValue(json, new TypeReference>(){});

4. Расширенные функции

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

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

4.1. Настройка функции сериализации или дезериализации

При преобразовании объектов JSON в классы Java в случае, если строка JSON имеет несколько новых полей, процесс по умолчанию приведет к исключению:

String jsonString 
  = "{ \"color\" : \"Black\", \"type\" : \"Fiat\", \"year\" : \"1970\" }";

Строка JSON в приведенном выше примере в процессе разбора по умолчанию на объект Java для Класс автомобильных приведет к НепризнанныйПропертиЭксцепция исключение.

Через настроить метод, мы можем расширить процесс по умолчанию, чтобы игнорировать новые поля :

objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
Car car = objectMapper.readValue(jsonString, Car.class);

JsonNode jsonNodeRoot = objectMapper.readTree(jsonString);
JsonNode jsonNodeYear = jsonNodeRoot.get("year");
String year = jsonNodeYear.asText();

Еще один вариант основан на FAIL_ON_NULL_FOR_PRIMITIVES , который определяет, если нулевой значения для примитивных значений допускаются:

objectMapper.configure(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES, false);

Аналогичным образом, FAIL_ON_NUMBERS_FOR_ENUM элементы управления, если значения enum разрешены к сериализации/дезериализации в качестве чисел:

objectMapper.configure(DeserializationFeature.FAIL_ON_NUMBERS_FOR_ENUMS, false);

Полный список функций сериализации и дезириализации можно найти на официальный сайт .

4.2. Создание пользовательского сериализатора или дезериализатора

Еще одна существенная особенность ОбъектМаппер класс – это возможность зарегистрировать пользовательский сериализатор и deserializer .

Пользовательские сериализаторы и deserializers очень полезны в ситуациях, когда вход или выход JSON ответ отличается по структуре, чем класс Java, в котором он должен быть сериализован или deserialized.

Ниже приведен пример пользовательского сериала JSON :

public class CustomCarSerializer extends StdSerializer {
    
    public CustomCarSerializer() {
        this(null);
    }

    public CustomCarSerializer(Class t) {
        super(t);
    }

    @Override
    public void serialize(
      Car car, JsonGenerator jsonGenerator, SerializerProvider serializer) {
        jsonGenerator.writeStartObject();
        jsonGenerator.writeStringField("car_brand", car.getType());
        jsonGenerator.writeEndObject();
    }
}

Этот пользовательский сериализатор может быть вызван так:

ObjectMapper mapper = new ObjectMapper();
SimpleModule module = 
  new SimpleModule("CustomCarSerializer", new Version(1, 0, 0, null, null, null));
module.addSerializer(Car.class, new CustomCarSerializer());
mapper.registerModule(module);
Car car = new Car("yellow", "renault");
String carJson = mapper.writeValueAsString(car);

Вот что такое Автомобильные выглядит как (как выход JSON) на стороне клиента:

var carJson = {"car_brand":"renault"}

И вот пример пользовательский JSON deserializer :

public class CustomCarDeserializer extends StdDeserializer {
    
    public CustomCarDeserializer() {
        this(null);
    }

    public CustomCarDeserializer(Class vc) {
        super(vc);
    }

    @Override
    public Car deserialize(JsonParser parser, DeserializationContext deserializer) {
        Car car = new Car();
        ObjectCodec codec = parser.getCodec();
        JsonNode node = codec.readTree(parser);
        
        // try catch block
        JsonNode colorNode = node.get("color");
        String color = colorNode.asText();
        car.setColor(color);
        return car;
    }
}

Этот пользовательский deserializer может быть вызван таким образом:

String json = "{ \"color\" : \"Black\", \"type\" : \"BMW\" }";
ObjectMapper mapper = new ObjectMapper();
SimpleModule module =
  new SimpleModule("CustomCarDeserializer", new Version(1, 0, 0, null, null, null));
module.addDeserializer(Car.class, new CustomCarDeserializer());
mapper.registerModule(module);
Car car = mapper.readValue(json, Car.class);

4.3. Обработка форматов дат

Сериализация по умолчанию java.util.Date производит число, т.е. эпоха таймштамп (количество миллисекунд с 1 января 1970 года, UTC). Но это не очень читаемый человек и требует дальнейшего преобразования, которые будут отображаться в человеческом читаемом формате.

Давайте завернем Автомобильные экземпляр мы использовали до сих пор внутри Запрос класс с датаПрофилированная свойство:

public class Request 
{
    private Car car;
    private Date datePurchased;

    // standard getters setters
}

Для управления форматом строки даты и установить его, например, yyyy-MM-dd HH:mm a z , рассмотрим следующий фрагмент:

ObjectMapper objectMapper = new ObjectMapper();
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm a z");
objectMapper.setDateFormat(df);
String carAsString = objectMapper.writeValueAsString(request);
// output: {"car":{"color":"yellow","type":"renault"},"datePurchased":"2016-07-03 11:43 AM CEST"}

Чтобы узнать больше о датах сериализации с Джексоном, прочитайте нашу более углубленную записи .

4.4. Обработка коллекций

Еще одна небольшая, но полезная функция, доступная через ДесериализацияФеатура класс — это возможность создавать коллекцию, которую мы хотим получить из ответа JSON Array.

Например, мы можем создать результат в массиве:

String jsonCarArray = 
  "[{ \"color\" : \"Black\", \"type\" : \"BMW\" }, { \"color\" : \"Red\", \"type\" : \"FIAT\" }]";
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.USE_JAVA_ARRAY_FOR_JSON_ARRAY, true);
Car[] cars = objectMapper.readValue(jsonCarArray, Car[].class);
// print cars

Или как Список :

String jsonCarArray = 
  "[{ \"color\" : \"Black\", \"type\" : \"BMW\" }, { \"color\" : \"Red\", \"type\" : \"FIAT\" }]";
ObjectMapper objectMapper = new ObjectMapper();
List listCar = objectMapper.readValue(jsonCarArray, new TypeReference>(){});
// print cars

Более подробная информация об обработке коллекций с Джексоном доступна здесь .

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

Джексон является твердой и зрелой библиотекой сериализации/дезериализации JSON для Java. ОбъектМаппер API предоставляет простой способ анализа и генерации объектов реагирования JSON с большой гибкостью. В этой статье обсуждались основные особенности, которые делают библиотеку настолько популярной.

Исходный код, который сопровождает статью, можно найти более чем на GitHub.