Пользовательский сериализатор и addKeySerializer, похоже, являются лучшим подходом, хотя создание модуля, добавление Serializer или KeySerializer и его регистрация с помощью картографов несколько сложнее.
Если по какой-либо причине (как вы заявили) вы не можете использовать собственный сериализатор. Ниже приведено несколько вариантов, которые могут вам помочь
Оба выдают результат
{"John":"abc"}
При написании карты, но оставить один объект без изменений
{"name":"John","age":20}
Потоки Java 8 для отображения на выходе
В зависимости от того, насколько сложны ваши реальные объекты, по сравнению с простым примером вы можете просто сделать отображение во время или перед вызовом writeValue.
mapper.writeValue(System.out,
map.entrySet().stream().collect(
Collectors.toConcurrentMap(
k -> k.getKey().getName(),
Function.identity())));
Реализация JsonSerializable в коллекции
Если вы можете изменить свою коллекцию на пользовательскую версию, которая расширяет HashMap.
class PersonHashMap extends HashMap<Person, String> implements JsonSerializable {
@Override
public void serialize(JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
jsonGenerator.writeStartObject();
for (Entry<Person, String> e : entrySet()) {
jsonGenerator.writeStringField(e.getKey().getName(), e.getValue());
}
jsonGenerator.writeEndObject();
}
@Override
public void serializeWithType(JsonGenerator jsonGenerator, SerializerProvider serializerProvider, TypeSerializer typeSerializer) throws IOException {
.
.
.
}
}
Недостаток в том, что вам нужно было бы контролировать инициализацию карты, чтобы сделать что-то вроде этого:
Map<Person, String> map = new PersonHashMap();
Но опять же, это все, что нужно, без дополнительного модуля или регистрации в вашем объектном картографическом устройстве, как если бы вы делали это с JsonSerializer.