Пользовательская сериализация условных карт с ДжексономJAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Пользовательская сериализация условных карт с Джексоном

Сообщение Anonymous »

Мне нужно условно сериализовать карту в строку. Т.е. когда Map соответствует некоторому условию, я хочу заменить весь полученный объект JSON одним пользовательским значением, например Нить. Я пытаюсь реализовать это следующим образом:

Код: Выделить всё

public class MapParseTest
{
private final ObjectMapper mapper;

public MapParseTest()
{
mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.setSerializerModifier(new MyMapSerializerModifier());
mapper.registerModule(module);
}

public void doTest() throws JsonProcessingException
{
MyMap map1 = new MyMap();
MyMap map2 = new MyMap();

map1.setName("shtame");
map2.setName("magic name");

map1.put("First", 1);
map1.put("Second", "Two");
map1.put("Third", map2);

map2.put("Eleventh", 11);
map2.put("Twelfth", "12");

String result = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(map1);
System.out.println(result);
}

public static void main(String[] args) throws JsonProcessingException
{
MapParseTest test = new MapParseTest();
test.doTest();
}

@Setter
@Getter
public static class MyMap extends HashMap
{
private String name;
}

public static class MyMapSerializer extends JsonSerializer
{
private final JsonSerializer defaultSerializer;

public MyMapSerializer(JsonSerializer defaultSerializer)
{
this.defaultSerializer = defaultSerializer;
}

@Override
public void serialize(MyMap value,
JsonGenerator gen,
SerializerProvider provider) throws IOException
{
String className = value.getName();
if (className.equalsIgnoreCase("magic name"))
{
gen.writeString("magic string");
} else
{
defaultSerializer.serialize(value, gen, provider);
}
}
}

public static class MyMapSerializerModifier extends BeanSerializerModifier
{
@Override
public JsonSerializer modifyMapSerializer(SerializationConfig config,
MapType mapType,
BeanDescription beanDesc,
JsonSerializer serializer)
{
Class type = beanDesc.getBeanClass();
if (type.equals(MyMap.class))
{
return new MyMapSerializer((JsonSerializer) serializer);
}
return serializer;
}
}
}
Я ожидаю, что это даст результат

Код: Выделить всё

{
"Second" : "Two",
"Third" : "magic string",
"First" : 1
}
вместо

Код: Выделить всё

{
"Second" : "Two",
"Third" : {
"Eleventh" : 11,
"Twelfth" : "12"
},
"First" : 1
}
Но вместо этого я получаю сообщение об ошибке:

Код: Выделить всё

Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException: Cannot invoke "com.fasterxml.jackson.databind.JsonSerializer.serialize(Object, com.fasterxml.jackson.core.JsonGenerator, com.fasterxml.jackson.databind.SerializerProvider)" because "keySerializer" is null (through reference chain: st.notexi.test.MapParseTest$MyMap["Second"])
Возможно, мне также придется реализовать модифицированиеKeySerializer, но я не понимаю, как это сделать, и не могу найти для этого никакой документации. Я понимаю, что в некоторых случаях заменяемая карта сама должна иметь ключ, например, если это корневая карта. Но как с этим бороться я не понимаю.
Помогите пожалуйста - как это можно реализовать?

Подробнее здесь: https://stackoverflow.com/questions/783 ... th-jackson
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»