I want to add a custom serializer and deserializer for JSR 363 javax.measure.Quantity<Q extends Quantity<Q>>
, which basically encapsulates a "value" and a "unit". Creating the serializer (extends JsonSerializer<Quantity<?>>
) and the deserializer (extends StdDeserializer<Quantity<?>>
) is easy.
But it's not easy to register them. For deserializers, it's OK; look at the signature:
SimpleModule.addDeserializer(Class<T> type, JsonDeserializer<? extends T> deser)
Notice that the deserializer allows the generic type to be extended. So I can do this:
module.addDeserializer(Quantity.class, new MyQuantityJsonDeserializer());
But the serializer is another story; look at the signature for its registration:
SimpleModule.addSerializer(Class<? extends T> type, JsonSerializer<T> ser)
Oh, the pain this causes because of the restricted generic type. I cannot do this:
module.addSerializer(Quantity.class, new MyQuantityJsonSerializer());
This is because Quantity.class
will never give me a Class<Quantity<Q extends Quantity<Q>>
. And there is no easy cast around this, without introducing some arbitrary generic variable in the module method and using acrobatic casts. Even this won't work:
module.addSerializer((Class<Quantity<?>>) Quantity.class, new MyQuantityJsonSerializer());
The best I've been able to do is to make my serializer class QuantityJsonSerializer<Q extends Quantity<Q>> extends JsonSerializer<Q>
, and then in the module register it as the raw type:
@SuppressWarnings({"rawtypes", "unchecked"})
final JsonSerializer<Quantity> quantitySerializer =
(JsonSerializer<Quantity>) new MyQuantityJsonSerializer();
module.addSerializer(Quantity.class, quantitySerializer);
Ugh, how ugly is that? But that is one of the only ways I can find to even get it to work, and I had to go through more gymnastics to remove the warnings.
Surely SimpleModule.addSerializer()
could have been a bit more flexible on its generic parameters, analogous to SimpleModule.addDeserializer()
?
I'm reporting this here because the Jackson project said to report bugs here --- and I'm also asking for better workaround ideas. Thanks.
In SimpleModule
there is an overloaded version of addSerializer()
:
public SimpleModule addSerializer(JsonSerializer<?> ser)
which allows this to work:
module.addSerializer(new MyQuantityJsonSerializer());
as long as you define your serializer as:
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...
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With