如何在自定义序列化程序中访问默认的 jackson 序列化

2022-09-01 09:58:50

我想创建一个自定义序列化程序,它做一点点工作,然后把其余的留给默认序列化。

例如:

@JsonSerialize(using = MyClassSerializer.class)
public class MyClass {
  ...
}

public class MyClassSerializer extends JsonSerializer<MyClass> {
    @Override
    public void serialize(MyClass myClass, JsonGenerator generator, 
                          SerializerProvider provider) 
            throws JsonGenerationException, IOException {
        if (myClass.getSomeProperty() == someCalculationResult) {
            provider.setAttribute("special", true);
        }
        generator.writeObject(myClass);
    }  
}

其想法是为聚合对象创建其他自定义序列化程序,这些对象的行为基于“特殊”属性值而有所不同。但是,上面的代码不起作用,因为它不出所料地进入了无限递归。

有没有办法告诉我,一旦我设置了属性,杰克逊就使用默认序列化?我真的不想像许多自定义序列化程序那样枚举所有属性,因为该类相当复杂,我不想在每次更改类时都必须对序列化程序进行双重维护。


答案 1

BeanSerializerModifier 将为您提供对默认序列化的访问。

将默认序列化程序注入自定义序列化程序

public class MyClassSerializer extends JsonSerializer<MyClass> {
    private final JsonSerializer<Object> defaultSerializer;

    public MyClassSerializer(JsonSerializer<Object> defaultSerializer) {
        this.defaultSerializer = checkNotNull(defaultSerializer);
    }

    @Override
    public void serialize(MyClass myclass, JsonGenerator gen, SerializerProvider provider) throws IOException {
        if (myclass.getSomeProperty() == true) {
            provider.setAttribute("special", true);
        }
        defaultSerializer.serialize(myclass, gen, provider);
    }
}

创建一个BeanSerializerModifierMyClass

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

注册序列化程序修饰符

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

答案 2
@JsonSerialize(using = MyClassSerializer.class)
public class MyClass {
...
}

public class MyClassSerializer extends JsonSerializer<MyClass> {
    @Override
     public void serialize(MyClass myClass, JsonGenerator generator, 
                      SerializerProvider provider) 
        throws JsonGenerationException, IOException {
        if (myClass.getSomeProperty() == someCalculationResult) {
            provider.setAttribute("special", true);
        } else {
            provider.defaultSerializeValue(myClass, generator);
        }
    }  
}

如果您只是像往常一样编写对象,请使用上述内容