Search code examples
javaspring-bootserializationjacksonjsonserializer

Jackson2ObjectMapperBuilder doesn't serialize object


I am using Spring Boot and it has it's own Jackson's default serialization. It works not correctly in scope of my task. So I want override Jackson's default serialization with my own custom serializator. Here is my code:

@Bean
public Jackson2ObjectMapperBuilder objectMapperBuilder() {
    return new Jackson2ObjectMapperBuilder() {
        @Override
        public void configure(ObjectMapper objectMapper) {
            super.configure(objectMapper);
            objectMapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
            SimpleModule simpleModule = new SimpleModule();
            simpleModule.addSerializer(ZonedDateTime.class, new ZonedDateTimeCustomSerializer());
            objectMapper.registerModule(simpleModule);
            objectMapper.configure(SerializationFeature.WRITE_DATE_KEYS_AS_TIMESTAMPS, false);
        }
    }.serializerByType(ZonedDateTime.class, new JsonSerializer<ZonedDateTime>() {
        @Override
        public void serialize(ZonedDateTime value,
                              JsonGenerator gen,
                              SerializerProvider serializerProvider) throws IOException {
            gen.writeString(value.getNano() + "");
        }
    });
}


private class ZonedDateTimeCustomSerializer extends JsonSerializer<ZonedDateTime> {
    @Override
    public void serialize(ZonedDateTime value, JsonGenerator gen, SerializerProvider provider) throws IOException {
        gen.writeString(value.getNano() + "");
    }
}

As you can see I tried some cases such as

  • registering custom serializator through SimpleModule
  • overriding Jackson2ObjectMapperBuilder#serialize

Please tip me how to override default Jackson serializator


Solution

  • #Slowpokebreakingnews

    If point is to add custom serializers - how about to customize Jackson2ObjectMapperBuilde by Jackson2ObjectMapperBuilderCustomizer:

    @Bean
    public Jackson2ObjectMapperBuilderCustomizer customizer()
    {
        return new Jackson2ObjectMapperBuilderCustomizer()
        {
            @Override
            public void customize(Jackson2ObjectMapperBuilder builder)
            {
                builder.serializerByType(CustomPojo.class, 
                                         new CustomSerializator<CustomPojo>());
                //affects to all dates in all pojos (I hope :) )
                builder.indentOutput(true).dateFormat(new SimpleDateFormat
                                                      ("yyyy-MM-dd'T'HH:mm:ssXXX"));
    
            }
        };
    }
    

    For without-Spring-boot-configuration I override configureMessageConverters() :

    @Configuration
    @EnableWebMvc
    ...
    public class WebConfig extends WebMvcConfigurerAdapter
    {
    
        @Override
        public void configureMessageConverters(List<HttpMessageConverter<?>> converters) 
        {
            Jackson2ObjectMapperBuilder builder = new CustomObjectMapperBuilder();
            converters.add(new MappingJackson2HttpMessageConverter(builder.build()));
        }
    
    }
    

    and define my CustomJackson2ObjectMapperBuilder:

    public class CustomObjectMapperBuilder extends Jackson2ObjectMapperBuilder
    {
        @Override
        public void configure(ObjectMapper objectMapper)
        {
            super.configure(objectMapper);
    
            SimpleModule module = new SimpleModule();
            module.addSerializer(Selective.class, new SelectiveSerializer());
    
            objectMapper.registerModule(module)
                .setSerializationInclusion(JsonInclude.Include.NON_NULL)
                .configure(JsonParser.Feature.ALLOW_COMMENTS, true)
                .configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true)
                .configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true)
                .configure(JsonParser.Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true)
                .disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
                .setDateFormat(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX"));
        }
    }