简体   繁体   English

Jackson模块签名可防止为自引用泛型类型添加序列化程序

[英]Jackson module signature prevents addings serializers for self-referencing generic types

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". 我想为JSR 363 javax.measure.Quantity<Q extends Quantity<Q>>添加一个自定义序列化器和反序列化器,它基本上封装了一个“值”和一个“单元”。 Creating the serializer ( extends JsonSerializer<Quantity<?>> ) and the deserializer ( extends StdDeserializer<Quantity<?>> ) is easy. 创建序列化器( extends JsonSerializer<Quantity<?>> )和反序列化器( extends StdDeserializer<Quantity<?>> )很容易。

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>> . 这是因为Quantity.class永远不会给我一个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: 我能做的最好的事情就是让我的序列化器类QuantityJsonSerializer<Q extends Quantity<Q>> extends JsonSerializer<Q> ,然后在模块中将它注册为原始类型:

@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() ? 当然, SimpleModule.addSerializer()可以在其通用参数上更灵活一些,类似于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() : SimpleModule有一个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...
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM