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

Сериализация и десериализация карт с помощью Джексона

Краткое и практическое руководство по сериализации и десериализации карт Java с использованием Jackson.

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

1. Обзор

В этой статье мы рассмотрим сериализацию и десериализацию карт Java с использованием Jackson .

Мы проиллюстрируем, как сериализовать и десериализовать Map String> , Map String>, и Map Object> в и из строк в формате JSON|/. String> ,

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

Джексон – Работа с картами и нулями

Как сериализовать и десериализовать перечисления с помощью Джексона

Сериализация и десериализация XML с помощью Jackson

2. Конфигурация Maven


    com.fasterxml.jackson.core
    jackson-databind
    2.11.1

Вы можете получить последнюю версию Jackson здесь .

3. Сериализация

Сериализация преобразует объект Java в поток байтов, который может быть сохранен или совместно использован по мере необходимости. Java Maps – это коллекции, которые сопоставляют ключ Объект со значением объектом и часто являются наименее интуитивно понятными объектами для сериализации.

3.1. Сериализация Map String> String>

Для простого случая давайте создадим Map String> и сериализуем его в JSON: String>

Map map = new HashMap<>();
map.put("key", "value");

ObjectMapper mapper = new ObjectMapper();
String jsonResult = mapper.writerWithDefaultPrettyPrinter()
  .writeValueAsString(map);

ObjectMapper -это картограф сериализации Джексона, который позволяет нам сериализовать нашу карту и записать ее в виде красиво напечатанного JSON String , используя метод toString() в String :

{
  "key" : "value"
}

3.2. Сериализация Map<Объект, строка>

Вы можете сериализовать карту, содержащую пользовательский класс Java, с помощью нескольких дополнительных шагов. Давайте создадим класс My Pair для представления пары связанных String объектов.

Примечание: геттеры/сеттеры должны быть общедоступными, и мы аннотируем toString() с помощью @JsonValue , чтобы убедиться, что Джексон использует этот пользовательский toString() при сериализации:

public class MyPair {

    private String first;
    private String second;
    
    @Override
    @JsonValue
    public String toString() {
        return first + " and " + second;
    }
 
    // standard getter, setters, equals, hashCode, constructors
}

Теперь давайте расскажем Джексону, как сериализовать Мою пару , расширив Джексона JsonSerializer :

public class MyPairSerializer extends JsonSerializer {

    private ObjectMapper mapper = new ObjectMapper();

    @Override
    public void serialize(MyPair value, 
      JsonGenerator gen,
      SerializerProvider serializers) 
      throws IOException, JsonProcessingException {
 
        StringWriter writer = new StringWriter();
        mapper.writeValue(writer, value);
        gen.writeFieldName(writer.toString());
    }
}

JsonSerializer , как следует из названия, сериализует MyPair в JSON с помощью метода My Pair ‘s toString () . Джексон предоставляет множество классов Сериализатора в соответствии с вашими требованиями к сериализации.

Мы применяем MyPairSerializer к нашей карте String> с аннотацией @JsonSerialize . Обратите внимание, что мы только сказали Джексону, как сериализовать Мою пару , потому что он уже знает, как сериализовать Строку: String>

@JsonSerialize(keyUsing = MyPairSerializer.class) 
Map map;

Давайте проверим нашу сериализацию карт:

map = new HashMap<>();
MyPair key = new MyPair("Abbott", "Costello");
map.put(key, "Comedy");

String jsonResult = mapper.writerWithDefaultPrettyPrinter()
  .writeValueAsString(map);

Сериализованный вывод JSON:

{
  "Abbott and Costello" : "Comedy"
}

3.3. Сериализация Map<Объект, объект>

Наиболее сложным случаем является сериализация Map Object> , но большая часть работы уже выполнена. Давайте используем/| MapSerializer Джексона для нашей карты и MyPairSerializer из предыдущего раздела для типов ключей и значений карты: Object> , но большая часть работы уже выполнена. Давайте используем/| MapSerializer Джексона

@JsonSerialize(keyUsing = MapSerializer.class)
Map map;
	
@JsonSerialize(keyUsing = MyPairSerializer.class)
MyPair mapKey;

@JsonSerialize(keyUsing = MyPairSerializer.class)
MyPair mapValue;

Давайте проверим сериализацию нашей карты MyPair> : MyPair>

mapKey = new MyPair("Abbott", "Costello");
mapValue = new MyPair("Comedy", "1940s");
map.put(mapKey, mapValue);

String jsonResult = mapper.writerWithDefaultPrettyPrinter()
  .writeValueAsString(map);

Сериализованный вывод JSON с использованием метода My Pair ‘s toString() :

{
  "Abbott and Costello" : "Comedy and 1940s"
}

4. Десериализация

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

4.1. Десериализация Map String> String>

Для простого случая давайте возьмем входную строку в формате JSON и преобразуем ее в коллекцию Map String> |/Java: String> |/Java:

String jsonInput = "{\"key\": \"value\"}";
TypeReference> typeRef 
  = new TypeReference>() {};
Map map = mapper.readValue(jsonInput, typeRef);

Мы используем ObjectMapper Джексона , как и для сериализации, используя read Value() для обработки входных данных. Кроме того, обратите внимание на использование Джексоном TypeReference , которое мы будем использовать во всех примерах десериализации, для описания типа нашего назначения Map . Вот toString() представление нашей карты:

{key=value}

4.2. Десериализация Map<Объект, строка>

Теперь давайте изменим наш входной JSON и ссылку на Тип нашего назначения на Map String> : String>

String jsonInput = "{\"Abbott and Costello\" : \"Comedy\"}";

TypeReference> typeRef 
  = new TypeReference>() {};
Map map = mapper.readValue(jsonInput, typeRef);

Нам нужно создать конструктор для My Pair , который принимает Строку с обоими элементами и анализирует их на элементы MyPair :

public MyPair(String both) {
    String[] pairs = both.split("and");
    this.first = pairs[0].trim();
    this.second = pairs[1].trim();
}

И toString() нашего Map объекта:

{Abbott and Costello=Comedy}

Есть еще один вариант для случая, когда мы десериализуемся в класс Java, содержащий Map — мы можем использовать KeyDeserializer class Джексона , один из многих классов десериализации , которые предлагает Джексон. Мы аннотируем наш Класс Картой с помощью @JsonCreator , @JsonProperty и @JsonDeserialize:

public class ClassWithAMap {

  @JsonProperty("map")
  @JsonDeserialize(keyUsing = MyPairDeserializer.class)
  private Map map;

  @JsonCreator
  public ClassWithAMap(Map map) {
    this.map = map;
  }
 
  // public getters/setters omitted
}

Мы говорим Джексону десериализовать Map String> , содержащийся в классе С картой , поэтому нам нужно расширить KeyDeserializer , чтобы описать, как десериализовать ключ карты, объект MyPair , из ввода String : String>

public class MyPairDeserializer extends KeyDeserializer {

  @Override
  public MyPair deserializeKey(
    String key, 
    DeserializationContext ctxt) throws IOException, 
    JsonProcessingException {
      
      return new MyPair(key);
    }
}

Мы тестируем десериализацию с помощью readValue :

String jsonInput = "{\"Abbott and Costello\":\"Comedy\"}";

ClassWithAMap classWithMap = mapper.readValue(jsonInput,
  ClassWithAMap.class);

Опять же, метод toString() нашего класса С картой map дает нам результат, который мы ожидаем:

{Abbott and Costello=Comedy}

4.3. Десериализация карты<Объект,объект>

Наконец, давайте изменим наш входной JSON и ссылку на Тип нашего назначения на Map MyPair> : MyPair>

String jsonInput = "{\"Abbott and Costello\" : \"Comedy and 1940s\"}";
TypeReference> typeRef 
  = new TypeReference>() {};
Map map = mapper.readValue(jsonInput, typeRef);

И toString() нашего Map MyPair> объекта: MyPair>

{Abbott and Costello=Comedy and 1940s}

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

В этом кратком руководстве мы рассмотрели, как сериализовать и десериализовать Java Maps в строки в формате JSON и из них.

Как всегда, вы можете проверить пример, приведенный в этой статье, в репозитории GitHub .