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

Gar*_*son 7 java generics jackson jsr363

我想为JSR 363添加一个自定义序列化器和反序列化器javax.measure.Quantity<Q extends Quantity<Q>>,它基本上封装了一个"值"和一个"单元".创建序列化程序(extends JsonSerializer<Quantity<?>>)和反序列化程序(extends StdDeserializer<Quantity<?>>)很容易.

但注册它们并不容易.对于反序列化器,它没关系; 看看签名:

SimpleModule.addDeserializer(Class<T> type, JsonDeserializer<? extends T> deser)
Run Code Online (Sandbox Code Playgroud)

请注意,反序列化器允许扩展泛型类型.所以我可以这样做:

module.addDeserializer(Quantity.class, new MyQuantityJsonDeserializer());
Run Code Online (Sandbox Code Playgroud)

但序列化器是另一个故事; 看看它的注册签名:

SimpleModule.addSerializer(Class<? extends T> type, JsonSerializer<T> ser)
Run Code Online (Sandbox Code Playgroud)

哦,由于受限的泛型类型导致的痛苦.我不能做到这一点:

module.addSerializer(Quantity.class, new MyQuantityJsonSerializer());
Run Code Online (Sandbox Code Playgroud)

这是因为Quantity.class永远不会给我一个Class<Quantity<Q extends Quantity<Q>>.并且没有简单的演员,没有在模块方法中引入一些任意的泛型变量并使用杂技演员.即使这样也行不通:

module.addSerializer((Class<Quantity<?>>) Quantity.class, new MyQuantityJsonSerializer());
Run Code Online (Sandbox Code Playgroud)

我能做的最好的事情是创建我的序列化程序类QuantityJsonSerializer<Q extends Quantity<Q>> extends JsonSerializer<Q>,然后在模块中将其注册为原始类型:

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

呃,那有多难看?但这是我能找到的唯一能让它上班的方法之一,我不得不通过更多的体操来消除警告.

肯定SimpleModule.addSerializer()可以在其通用参数上更灵活,类似于SimpleModule.addDeserializer()

我在这里报道这是因为杰克逊项目在这里报告错误 - 我也要求更好的解决方法.谢谢.

ck1*_*ck1 5

SimpleModule其中有一个重载版本addSerializer()

public SimpleModule addSerializer(JsonSerializer<?> ser)
Run Code Online (Sandbox Code Playgroud)

这可以使它工作:

module.addSerializer(new MyQuantityJsonSerializer());
Run Code Online (Sandbox Code Playgroud)

只要您将序列化程序定义为:

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...
    }
}
Run Code Online (Sandbox Code Playgroud)