Override JSON properties in @RestController in Spring 4.3.3 WebMVC

210 Views Asked by At

I want to override the following properties in Spring RestController in WebMVC.

objectMapper.setSerializationInclusion(Include.NON_NULL);
objectMapper.configure(SerializationFeature.WRAP_ROOT_VALUE, true);
objectMapper.setDateFormat(DATEFORMAT);

I've tried the following in multiple combinations, but nothing worked. Still getting the null value without root name in the response.

@EnableWebMvc
public class ApplicationContextConfig extends WebMvcConfigurerAdapter {

     @Override
     public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        //MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter();
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        objectMapper.setSerializationInclusion(Include.NON_NULL);
        objectMapper.configure(SerializationFeature.WRAP_ROOT_VALUE, true);
        objectMapper.setDateFormat(DATEFORMAT);
        //jsonConverter.setObjectMapper(objectMapper);
        MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter(objectMapper);
        //jsonConverter.setJsonPrefix(jsonPrefix);
        converters.add(jsonConverter);
     }

    @Override
    public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        for (HttpMessageConverter<?> converter : converters) {
            if (converter instanceof MappingJackson2HttpMessageConverter) {
                MappingJackson2HttpMessageConverter jsonMessageConverter = (MappingJackson2HttpMessageConverter) converter;
                ObjectMapper objectMapper = jsonMessageConverter.getObjectMapper();
                objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
                objectMapper.setSerializationInclusion(Include.NON_NULL);
                objectMapper.configure(SerializationFeature.WRAP_ROOT_VALUE, true);
                objectMapper.setDateFormat(DATEFORMAT);
                break;
            }
        }
    }

    @Bean
    @Primary
    public ObjectMapper getObjectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setSerializationInclusion(Include.NON_NULL);
        objectMapper.configure(SerializationFeature.WRAP_ROOT_VALUE, true);
        objectMapper.setDateFormat(DATEFORMAT);
        return objectMapper;
    }
}

Reponse:

{
    "Message": null,
    "Admin": null,
    "Company": null
}
1

There are 1 best solutions below

1
Mark Bramnik On

You should "substitute" the object mapper bean provided by spring with your own and configure it.

@Configuration
public class MyJacksonCustomConfiguration {

    @Bean
    public ObjectMapper objectMapper() { // note the name should be 'objectMapper'
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setSerializationInclusion(Include.NON_NULL);
        objectMapper.configure(SerializationFeature.WRAP_ROOT_VALUE, true);
        objectMapper.setDateFormat(DATEFORMAT);        
        return objectMapper;
    }
}

All in all, make sure that only one bean of type object mapper should exist in the application context. Apart of fact that its a pretty "heavy" object, if spring will inject a wrong mapper you won't be able to benefit from customization that you've done.