Java Apache Pair сериализует в одном формате и десериализует в другом формате, используя сериализацию Джексона

При сериализации Apache Mutable Pair с использованием аннотации Jackson@JsonSerialize создается такая структура

{"leftValue": "rightValue"}

но для обработки во время десериализации с использованием аннотации Jackson@JsonDeserialize ожидается эта структура

{
"left":"leftValue",
"right": "rightValue"
}

Такие методы, как getLeft() или getValue(), возвращают null, когда используется первая структура, но возвращают правильные значения в случае второй структуры.

Как его можно сериализовать во вторую структуру? И какая рекомендуемая структура?

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
0
894
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

org.apache.commons.lang3.tuple.MutablePair расширяет Pair, реализующий Map.Entry интерфейс. Map.Entry по умолчанию обрабатывается Jackson как Map объект, который сериализуется в JSON как key-value структура. Чтобы сериализовать его как классический POJO, нам нужно реализовать собственный сериализатор, который будет определять правильную структуру:

class MutablePairJsonSerializer extends JsonSerializer<MutablePair> {

    @Override
    public void serialize(MutablePair value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        gen.writeStartObject();
        gen.writeObjectField("left", value.getLeft());
        gen.writeObjectField("right", value.getRight());
        gen.writeEndObject();
    }
}

Простое приложение, которое использует вышеуказанный сериализатор:

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.module.SimpleModule;
import org.apache.commons.lang3.tuple.MutablePair;

import java.io.IOException;

public class JsonApp {

    public static void main(String[] args) throws Exception {
        MutablePair<String, String> pair = new MutablePair<>();
        pair.setLeft("leftV");
        pair.setRight("rightV");

        SimpleModule pairModule = new SimpleModule();
        pairModule.addSerializer(MutablePair.class, new MutablePairJsonSerializer());

        ObjectMapper mapper = new ObjectMapper();
        mapper.enable(SerializationFeature.INDENT_OUTPUT);
        mapper.registerModule(pairModule);

        String json = mapper.writeValueAsString(pair);
        System.out.println(json);
        System.out.println(mapper.readValue(json, MutablePair.class));
    }
}

печатает:

{
  "left" : "leftV",
  "right" : "rightV"
}
(leftV,rightV)

Что показывает, что объект сериализуется с помощью ключей и правильно десериализуется в объект.

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

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.module.SimpleModule;
import org.apache.commons.lang3.tuple.MutablePair;

import java.io.IOException;

public class JsonApp {

    public static void main(String[] args) throws Exception {
        MutablePair<String, String> pair = new MutablePair<>();
        pair.setLeft("leftV");
        pair.setRight("rightV");

        SimpleModule pairModule = new SimpleModule();
        pairModule.addDeserializer(MutablePair.class, new MutablePairJsonDeserializer());

        ObjectMapper mapper = new ObjectMapper();
        mapper.enable(SerializationFeature.INDENT_OUTPUT);
        mapper.registerModule(pairModule);

        String json = mapper.writeValueAsString(pair);
        System.out.println(json);
        System.out.println(mapper.readValue(json, MutablePair.class));
    }
}

class MutablePairJsonDeserializer extends JsonDeserializer<MutablePair> {

    @Override
    public MutablePair deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        p.nextToken(); // SKIP START_OBJECT
        String keyName = p.getCurrentName();
        p.nextToken();

        return MutablePair.of(keyName, p.getValueAsString());
    }
}

Другие вопросы по теме