Jackson: How to add custom property to the JSON without modifying the POJO

后端 未结 11 1279
南方客
南方客 2020-11-27 03:10

I am developing a REST interface for my app using Jackson to serialize my POJO domain objects to JSON representation. I want to customize the serialization for some types to

11条回答
  •  轮回少年
    2020-11-27 03:48

    Inspired from what wajda said and written in this gist:

    Here is how to add a listener for bean serialization in jackson 1.9.12. In this example, the listerner is considered as a Chain Of Command which interface is :

    public interface BeanSerializerListener {
        void postSerialization(Object value, JsonGenerator jgen) throws IOException;
    }
    

    MyBeanSerializer.java:

    public class MyBeanSerializer extends BeanSerializerBase {
        private final BeanSerializerListener serializerListener;
    
        protected MyBeanSerializer(final BeanSerializerBase src, final BeanSerializerListener serializerListener) {
            super(src);
            this.serializerListener = serializerListener;
        }
    
        @Override
        public void serialize(final Object bean, final JsonGenerator jgen, final SerializerProvider provider) throws IOException, JsonGenerationException {
            jgen.writeStartObject();
            if (_propertyFilterId != null) {
                serializeFieldsFiltered(bean, jgen, provider);
            } else {
                serializeFields(bean, jgen, provider);
            }
    
            serializerListener.postSerialization(bean, jgen);
    
            jgen.writeEndObject();
        }
    }
    

    MyBeanSerializerBuilder.java:

    public class MyBeanSerializerBuilder extends BeanSerializerBuilder {
        private final BeanSerializerListener serializerListener;
    
        public MyBeanSerializerBuilder(final BasicBeanDescription beanDesc, final BeanSerializerListener serializerListener) {
            super(beanDesc);
            this.serializerListener = serializerListener;
        }
    
        @Override
        public JsonSerializer build() {
            BeanSerializerBase src = (BeanSerializerBase) super.build();
            return new MyBeanSerializer(src, serializerListener);
        }
    }
    

    MyBeanSerializerFactory.java:

    public class MyBeanSerializerFactory extends BeanSerializerFactory {
    
        private final BeanSerializerListener serializerListener;
    
        public MyBeanSerializerFactory(final BeanSerializerListener serializerListener) {
            super(null);
            this.serializerListener = serializerListener;
        }
    
        @Override
        protected BeanSerializerBuilder constructBeanSerializerBuilder(final BasicBeanDescription beanDesc) {
            return new MyBeanSerializerBuilder(beanDesc, serializerListener);
        }
    }
    

    The last class below shows how to provide it using Resteasy 3.0.7:

    @Provider
    public class ObjectMapperProvider implements ContextResolver {
        private final MapperConfigurator mapperCfg;
    
        public ObjectMapperProvider() {
            mapperCfg = new MapperConfigurator(null, null);
            mapperCfg.setAnnotationsToUse(new Annotations[]{Annotations.JACKSON, Annotations.JAXB});
            mapperCfg.getConfiguredMapper().setSerializerFactory(serializerFactory);
        }
    
        @Override
        public ObjectMapper getContext(final Class type) {
            return mapperCfg.getConfiguredMapper();
        }
    }
    

提交回复
热议问题