如何为杰克逊编写一个全能(de)序列化器 [英] How to write a catch-all (de)serializer for Jackson
问题描述
如果事先知道类型,编写自定义序列化程序非常简单。例如。 MyType
可以写一个 MyTypeSerializer扩展StdSerializer< MyType>
。请参阅 http://wiki.fasterxml.com/JacksonHowToCustomSerializers
Writing a custom serializer is pretty easy when you know the type in advance. For eg. MyType
one can write a MyTypeSerializer extends StdSerializer<MyType>
. See http://wiki.fasterxml.com/JacksonHowToCustomSerializers
但是,让我们说:
- 我有几种类型(接口)的对象通过杰克逊序列化。
- 我事先并不知道论文的类型。
- 我不能在这些类型上添加注释。
- 所有这些objets都可以转换为我知道的常见类型,以便我可以获取其状态数据,类型不属于其界面。
- I have objects of several types (interfaces) going through Jackson serialization.
- I don't know the type of theses objets in advance.
- I can't add annotations on theses types.
- all theses objets can be cast to a common type I know so that I can get its state data, type that is not part of their interface.
这意味着我需要编写一个应该处理所有类型的串行器(catch-all)并且可以决定它是否支持它(4.)。我天真地试过 CatchAllSerializer扩展了StdSerializer< Object>
但它根本没有触发。
This means I need to write a Serializer that should handle all types ("catch-all") and can decide if it supports it (4.). I've naïvely tried a CatchAllSerializer extends StdSerializer<Object>
but it's not triggered at all.
如何写/注册一个能捕获所有类型的序列化器,可以决定它是否支持给定的类型并提供序列化机制?
How do one write/register a serializer that will catch all types, can decide if it support a given type and provide serialization mechanism?
推荐答案
你可以设置 c $ c> ObjectMapper 的> BeanSerializerModifier覆盖委托序列化程序中的所有bean序列化程序,它决定使用哪种形式的序列化,具体取决于对象类型。
You can set a BeanSerializerModifier for the ObjectMapper
to override all the bean serializers on your a delegating serializer that decides which form of serialization to use depending on the object type.
以下是一个例子:
public class JacksonSerializerModifier {
public static interface A {
}
public static class B implements A {
public String field1 = "value1";
@Override
public String toString() {
return field1;
}
}
public static class C implements A {
public String field2 = "value2";
@Override
public String toString() {
return field2;
}
}
public static class D {
public String field3 = "value3";
}
private static class MyTypeSerializer extends JsonSerializer<Object> {
private final JsonSerializer<Object> delegate;
@SuppressWarnings("unchecked")
public MyTypeSerializer(JsonSerializer<?> delegate) {
this.delegate = (JsonSerializer<Object>) delegate;
}
@Override
public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider)
throws IOException {
if (value instanceof A) {
jgen.writeString(value.toString());
} else {
delegate.serialize(value, jgen, provider);
}
}
}
public static void main(String[] args) throws JsonProcessingException {
SimpleModule module = new SimpleModule();
module.setSerializerModifier(new BeanSerializerModifier() {
@Override
public JsonSerializer<?> modifySerializer(SerializationConfig config,
BeanDescription beanDesc,
JsonSerializer<?> serializer) {
return new MyTypeSerializer(serializer);
}
});
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(module);
System.out.println(mapper.writeValueAsString(Arrays.asList(new B(), new C(), new D())));
}
}
输出:
["value1","value2",{"field3":"value3"}]
这篇关于如何为杰克逊编写一个全能(de)序列化器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!