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