How to access default jackson serialization in a custom serializer

后端 未结 4 1765
梦如初夏
梦如初夏 2020-12-05 10:15

I want to create a custom serializer which does a tiny bit of work and then leaves the rest for default serialization.

For example:

@JsonSerialize(u         


        
相关标签:
4条回答
  • 2020-12-05 10:43
    @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);
    
        }  
    }
    

    if you are just writing an object as normal use the above

    0 讨论(0)
  • 2020-12-05 10:43

    You can use @JsonGetter instead of using a custom serializer if that's the only change you want to make.

    public class MyClass{
    
        @JsonGetter("special")
        protected boolean getSpecialForJackson() {
            return myClass.getSomeProperty() == someCalculationResult;
        }
    
    }
    
    0 讨论(0)
  • 2020-12-05 10:55

    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()));
    
    0 讨论(0)
  • 2020-12-05 10:59

    To add to the chosen answer, the serializer implementation may also have to implement ContextualSerializer and ResolvableSerializer interfaces. Please take a look at a related issue here https://github.com/FasterXML/jackson-dataformat-xml/issues/259

    public class MyClassSerializer extends JsonSerializer<MyClass>
        implements ContextualSerializer, ResolvableSerializer {
    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);
    }
    
    @Override
    public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property)
            throws JsonMappingException {
        if (defaultSerializer instanceof ContextualSerializer) {
            JsonSerializer<?> contextual = ((ContextualSerializer)defaultSerializer).createContextual(prov, property);
            return new MyClassSerializer((JsonSerializer<Object>)contextual);
        }
        return new MyClassSerializer(defaultSerializer);
    }
    
    @Override
    public void resolve(SerializerProvider provider) throws JsonMappingException {
        if (defaultSerializer instanceof ResolvableSerializer) {
            ((ResolvableSerializer)defaultSerializer).resolve(provider);
        }
    }
    

    }

    0 讨论(0)
提交回复
热议问题