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

Я хочу добавить собственный сериализатор и десериализатор для JSR 363 javax.measure.Quantity<Q extends Quantity<Q>>, который в основном заключает в себе "значение" и "единицу". Создание сериализатора (extends JsonSerializer<Quantity<?>>) и десериализатор (extends StdDeserializer<Quantity<?>>) это просто.

Но их нелегко зарегистрировать. Для десериализаторов это нормально; посмотрите на подпись:

SimpleModule.addDeserializer(Class<T> type, JsonDeserializer<? extends T> deser)

Обратите внимание, что десериализатор позволяет расширять универсальный тип. Так что я могу сделать это:

module.addDeserializer(Quantity.class, new MyQuantityJsonDeserializer());

Но сериализатор - это другая история; посмотрите на подпись для ее регистрации:

SimpleModule.addSerializer(Class<? extends T> type, JsonSerializer<T> ser)

О, боль, которую это вызывает из-за ограниченного родового типа. Я не могу сделать это:

module.addSerializer(Quantity.class, new MyQuantityJsonSerializer());

Это потому что Quantity.class никогда не даст мне Class<Quantity<Q extends Quantity<Q>>, И это не так просто сделать, не введя какую-либо произвольную переменную общего характера в методе модуля и не используя акробатические приведения. Даже это не сработает

module.addSerializer((Class<Quantity<?>>) Quantity.class, new MyQuantityJsonSerializer());

Лучшее, что я смог сделать, это сделать класс сериализатора QuantityJsonSerializer<Q extends Quantity<Q>> extends JsonSerializer<Q>, а затем в модуле зарегистрируйте его как необработанный тип:

@SuppressWarnings({"rawtypes", "unchecked"})
final JsonSerializer<Quantity> quantitySerializer =
    (JsonSerializer<Quantity>) new MyQuantityJsonSerializer();
module.addSerializer(Quantity.class, quantitySerializer);

Тьфу, как это уродливо? Но это один из немногих способов, которые я могу найти, чтобы заставить его работать, и мне пришлось пройти через дополнительную гимнастику, чтобы убрать предупреждения.

конечно SimpleModule.addSerializer() мог бы быть немного более гибким по своим общим параметрам, аналогичным SimpleModule.addDeserializer()?

Я сообщаю об этом здесь, потому что проект Джексона сказал сообщать об ошибках здесь - и я также прошу лучшие идеи обходного пути. Благодарю.

1 ответ

В SimpleModule есть перегруженная версия addSerializer():

public SimpleModule addSerializer(JsonSerializer<?> ser)

что позволяет это работать:

module.addSerializer(new MyQuantityJsonSerializer());

до тех пор, пока вы определяете ваш сериализатор как:

public class MyQuantityJsonSerializer extends StdSerializer<Quantity<?>> {
    public MyQuantityJsonSerializer() {
        // Note: second argument here is ignored.
        super(Quantity.class, false);
    }

    @Override
    public void serialize(Quantity<?> value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        // Serialize value here...
    }
}
Другие вопросы по тегам