【问题标题】:How to write a catch-all (de)serializer for Jackson如何为 Jackson 编写一个包罗万象的(反)序列化程序
【发布时间】:2014-07-29 12:32:30
【问题描述】:

如果您事先知道类型,编写自定义序列化程序非常容易。例如。 MyType 可以写一个MyTypeSerializer extends StdSerializer<MyType>。见http://wiki.fasterxml.com/JacksonHowToCustomSerializers

但是,让我们这么说:

  1. 我有几种类型的对象(接口)通过 Jackson 序列化。
  2. 我事先不知道这些对象的类型。
  3. 我无法在这些类型上添加注释。
  4. 所有这些对象都可以转换为我知道的通用类型,以便我可以获取其状态数据,该类型不是其接口的一部分。

这意味着我需要编写一个序列化程序来处理所有类型(“catch-all”)并且可以决定它是否支持它(4.)。我天真地尝试了CatchAllSerializer extends StdSerializer<Object>,但它根本没有被触发。

如何编写/注册一个可以捕获所有类型的序列化程序,以确定它是否支持给定类型并提供序列化机制?

【问题讨论】:

  • 我用ObjectMapper().writeValueAsString()
  • @OldCurmudgeon 这会触发默认的 Jackson 序列化,但问题是关于触发自定义序列化程序。

标签: java json serialization jackson


【解决方案1】:

您可以为ObjectMapper 设置BeanSerializerModifier 以覆盖委托序列化程序上的所有bean 序列化程序,该委托序列化程序根据对象类型决定使用哪种形式的序列化。

这是一个例子:

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"}]

【讨论】:

  • 感谢您的回答阿列克谢。如果测试是isAssignableFrom,你明白了,你的代码可以工作,但在我的用例中,我需要对对象本身进行处理,以查看我的自定义序列化程序是否能够序列化它,而不仅仅是它的类。有什么线索吗?
  • 换句话说,我想获得对要序列化的对象实例的引用,而不是BeanDescription
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-06-27
  • 2011-07-10
  • 1970-01-01
  • 2011-12-16
  • 1970-01-01
  • 2018-08-30
  • 2020-11-14
相关资源
最近更新 更多