Как я могу объявить переменную карты, используя Generics, которая имеет класс X в качестве ключа и соответствующий сериализатор X в качестве значения.
Например, я хочу иметь карту, которая может содержать:
К, В BigDecimal.class, новый BigDecimalSerializer() LocalDate.class, новый LocalDateSerializer() Date.class, новый DateSerializer()
Пример сериализатора:
public class BigDecimalSerializer extends JsonSerializer<BigDecimal> {
@Override
public void serialize(BigDecimal value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
gen.writeString(FormatUtils.format(value));
}
}
Я пробовал Map<Class<?>, ? extends JsonSerializer<?>>
@Getter
@AllArgsConstructor
public class CsvWriterConfig {
private final Map<Class<?>, ? extends JsonSerializer<?>> serializers;
private final char separator;
}
Но добавляя их в SimpleModule
SimpleModule module = new SimpleModule();
serializers.forEach(module::addSerializer);
Дает мне ошибку:
The type SimpleModule does not define addSerializer(Class<capture#5-of ?>, capture#4-of ? extends JsonSerializer<?>) that is applicable here
SimpleModule addSerializer:
public <T> SimpleModule addSerializer(Class<? extends T> type, JsonSerializer<T> ser)
{
_checkNotNull(type, "type to register serializer for");
_checkNotNull(ser, "serializer");
if (_serializers == null) {
_serializers = new SimpleSerializers();
}
_serializers.addSerializer(type, ser);
return this;
}
В настоящее время для него нет хорошего решения.
Один из возможных подходов - использовать необработанные типы (и вообще удалять дженерики)
Другим было бы добавить метод для добавления сериализаторов в модуль и приведения типов внутри метода:
@SuppressWarnings("unchecked")
private <T> void addSerializers(SimpleModule module) {
this.serializers.forEach((type, serializer) ->
module.addSerializer((Class<? extends T>) type, (JsonSerializer<T>) serializer));
}
Кстати, приведенный выше код взят из исходников spring-web
Третий подход заключается в создании оболочки для карты с методами доступа, что гарантирует, что не будут добавлены неправильные пары тип-сериализатор. например.:
SerializersWrapper serializersWrapper = new SerializersWrapper();
SimpleModule module = new SimpleModule();
serializersWrapper.getAll().forEach(module::addSerializer);
И код оболочки
import com.fasterxml.jackson.databind.JsonSerializer;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
public class SerializersWrapper {
private final Map<Class,JsonSerializer> serializers = new HashMap<>();
public <T> void addSerializer(Class<T> type, JsonSerializer<T> serializer) {
serializers.put(type, serializer);
}
public <T> JsonSerializer<T> getSerializer(Class<T> type){
return serializers.get(type);
}
public <T> Map<Class<T>,JsonSerializer<T>> getAll(){
return (Map<Class<T>, JsonSerializer<T>>) (Map) Collections.unmodifiableMap(serializers);
}
}