Java Apache Pair Сериализует в одном формате и десериализует в другом формате с использованием Jackson Serialize. - PullRequest
0 голосов
/ 09 апреля 2019

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

{"leftValue": "rightValue"}

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

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

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

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

1 Ответ

0 голосов
/ 09 апреля 2019

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());
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...