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

Dav*_*idA 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);
    }  
}
Run Code Online (Sandbox Code Playgroud)

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

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

Sam*_*rry 23

A 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

创建一个BeanSerializerModifierforMyClass

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

注册序列化修饰符

ObjectMapper om = new ObjectMapper()
        .registerModule(new SimpleModule()
                .setSerializerModifier(new MyClassSerializerModifier()));
Run Code Online (Sandbox Code Playgroud)

  • 这样就无需在类上使用`@JsonSerialize`. (2认同)
  • 这对我不起作用。尽管自定义序列化器的 serialize() 方法和其中的 setAttribute() 被调用,但添加(或修改)的属性并未反映在最终的 json 输出中。(顺便说一句, setAttribute() 可以添加一些额外的字段还是只修改现有的字段?) (2认同)

Law*_*ach 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);

    }  
}
Run Code Online (Sandbox Code Playgroud)

如果你只是正常写一个对象使用上面的

  • 您正在调用provider.defaultSerializer()来序列化MyClass的对象,该对象使用MyClassSerialzer进行序列化.现在,默认的jackson序列化程序不可能在类上遇到@JsonSerialize注释并调用MyClassSerialzer的serialize方法吗?这可能形成无休止的循环. (4认同)
  • 这确实引发了StackOverfliwError (3认同)
  • 这不会返回 stackOverflowError 吗? (2认同)