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

时间:2015-06-25 16:49:21

标签: java json jackson

我想创建一个自定义序列化程序,它可以完成一些工作,然后将其余部分用于默认序列化。

例如:

@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);
    }  
}

考虑为聚合对象创建其他自定义序列化程序,这些序列化程序根据'speical'属性值表现不同。但是,上面的代码不起作用,因为毫无疑问会进入无限递归。

有没有办法告诉jackson在设置属性后使用默认序列化?我真的不想像许多自定义序列化器一样枚举所有属性,因为类很复杂,我不想每次更改类时都要对序列化程序进行双重维护。

4 个答案:

答案 0 :(得分:23)

A BeanSerializerModifier will provide you access to the default serialization.

Inject a default serializer into the custom serializer

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);
    }
}

Create a BeanSerializerModifier for MyClass

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;
    }
}

Register the serializer modifier

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

答案 1 :(得分:5)

@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);
        }
        provider.defaultSerializeValue(myClass, generator);
    }  
}

如果您只是正常编写对象,请使用上面的

答案 2 :(得分:0)

如果这是您要进行的唯一更改,则可以使用@JsonGetter代替自定义序列化器。

public class MyClass{

    @JsonGetter("special")
    protected boolean getSpecialForJackson() {
        return myClass.getSomeProperty() == someCalculationResult;
    }

}

答案 3 :(得分:0)

要添加到选择的答案中,串行器实现可能还必须实现(define (alternating? lst) (cond [(empty? lst) true] [(> (first lst) 0) (cond [(< (first (rest lst) 0)) (alternating? (rest lst))])] [(< (first lst) 0) (cond [(> (first (rest lst) 0)) (alternating? (rest lst))])] [else false])) ContextualSerializer接口。请在这里查看相关问题 https://github.com/FasterXML/jackson-dataformat-xml/issues/259

ResolvableSerializer

}