【问题标题】:How to override isEmpty method of JsonSerializer for specific class without overriding serialize method?如何在不覆盖序列化方法的情况下覆盖特定类的 JsonSerializer 的 isEmpty 方法?
【发布时间】:2015-09-10 13:35:42
【问题描述】:

我想为 isEmpty 方法添加自定义行为。

当我从JsonSerializer<MySpecificClass>扩展时

我应该重写序列化方法,因为它是抽象的。

我想保留序列化方法,只覆盖 isEmpty 方法。

【问题讨论】:

    标签: java json spring serialization jackson


    【解决方案1】:

    为了修改isEmpty 行为但保持默认序列化,您可以利用序列化器修饰符。您仍然需要实现自定义序列化程序,但您可以非常干净地利用默认序列化。

    使用注入的默认序列化程序创建自定义序列化程序

    defaultSerializer 变量注入您的自定义序列化程序类。当我们实现修饰符时,您将看到这个序列化程序的来源。在这个类中,您将重写 isEmpty 方法来完成您需要的操作。下面,如果MySpecificClass 有一个空的id,Jackson 认为它是空的。

    public class MySpecificClassSerializer extends JsonSerializer<MySpecificClass> {
        private final JsonSerializer<Object> defaultSerializer;
    
        public MySpecificClassSerializer(JsonSerializer<Object> defaultSerializer) {
            this.defaultSerializer = checkNotNull(defaultSerializer);
        }
    
        @Override
        public void serialize(MySpecificClass value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
            defaultSerializer.serialize(value, gen, serializers);
        }
    
        @Override
        public boolean isEmpty(SerializerProvider provider, MySpecificClass value) {
            return value.id == null;
        }
    }
    

    创建自定义BeanSerializerModifier

    扩展BeanSerializerModifier 并覆盖modifySerializer 方法。在此方法中,您可以过滤要操作的类类型,并相应地返回您的自定义序列化程序。

    public class MyClassSerializerModifier extends BeanSerializerModifier {
        @Override
        public JsonSerializer<?> modifySerializer(SerializationConfig config, BeanDescription beanDesc, JsonSerializer<?> serializer) {
            if (beanDesc.getBeanClass() == MySpecificClass.class) {
                return new MySpecificClassSerializer((JsonSerializer<Object>) serializer);
            }
            return serializer;
        }
    }
    

    ObjectMapper注册修饰符

    注册修饰符将允许您的序列化程序在满足modifySerializer 中的条件时触发。

    ObjectMapper om = new ObjectMapper()
            .registerModule(new SimpleModule()
                    .setSerializerModifier(new MyClassSerializerModifier()));
    

    【讨论】:

    • 方法 MySpecificClassSerializer#serialize 调用,但 MySpecificClassSerializer#isEmpty - 不是
    • 您可能需要在父类上指定包含规则:@JsonInclude(JsonInclude.Include.NON_EMPTY) 或使用setSerializationInclusionObjectMapper 上全局指定。
    • 是的,你是对的。请解释如何注册几个 SerializeModifiers ?
    • 你可以链接registerModule。您需要为每个序列化器修饰符实例化一个新模块。您还可以使用单个修饰符并使用 BeanDescription#getBeanClass() 检查您的各种类。
    【解决方案2】:

    最后,你必须有一个 serialize 方法的实现,因为它是抽象的。如果至少有一个方法是抽象的,你就不能实例化你的类

    【讨论】:

    • 如果我不写自定义序列化器默认实现使用。我想改变一下
    • @gstackoverflow 我查看了 jackson-mapper-asl 1.8.6 中的 org.codehaus.jackson.map.JsonSerializer ,但没有看到任何“默认实现”,只有抽象定义。你在哪里看到的?
    • 我的意思是,如果你不写自定义序列化器,jackson 无论如何都可以将你的对象转换成json格式
    • com.fasterxml.jackson.databind.ser.DefaultSerializerProvider
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-09-09
    • 1970-01-01
    • 2011-12-23
    • 2012-06-14
    • 2012-02-08
    • 2021-06-11
    • 1970-01-01
    相关资源
    最近更新 更多