#java #json #apache #rest #jackson
#java #json #апач #остальное #джексон #apache
Вопрос:
При сериализации Apache Mutable Pair
с помощью Jackson
@JsonSerialize
аннотации создается такая структура
{"leftValue": "rightValue"}
но для обработки во время десериализации с использованием Jackson
@JsonDeserialize
аннотации ожидается такая структура
{
"left":"leftValue",
"right": "rightValue"
}
Такие методы, как getLeft()
or getValue()
, возвращают null
при использовании первой структуры, но возвращают правильные значения в случае второй структуры.
Как это может быть сериализовано во вторую структуру? Также какая структура рекомендуется?
Ответ №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)
Который показывает, что объект сериализуется с помощью ключей и десериализуется должным образом для object.
Если мы хотим сохранить процесс сериализации по умолчанию, нам нужно настроить десериализатор, который может выглядеть следующим образом:
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());
}
}