Search code examples
javaspringspring-mvcjacksonspring-annotations

Null values returned using WebMvcConfigurationSupport instead of WebMvcConfigurerAdapter


As WebMvcConfigurerAdapter is deprecated as of Spring 5.0, I have changed it to WebMvcConfigurationSupport, but I get null values in response.

{
"key": null,
"value": null,
"name":"test"
}

If I change it back to WebMvcConfigurerAdapter, I get the expected response:

{
"name":"test"
}

Spring version: 5.7.0 Jackson Version: 2.9.7

I have googled a lot of things but still no luck. I don't want to use the deprecated class. Tried removing @EnableWebMvc annotation after adding WebMvcConfigurationSupport as it's not required.

I have overridden configureMessageConverters where I setup MappingJackson2HttpMessageConverter with the inclusion NOT_NULL

@Configuration
@EnableAspectJAutoProxy
@EnableSwagger2
@PropertySource("classpath:test.properties")
@ComponentScan(basePackages = {"com.test.web"})
public class UmwWebConfig extends WebMvcConfigurationSupport {

@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        ByteArrayHttpMessageConverter bahHumbug = new ByteArrayHttpMessageConverter();
        bahHumbug.setSupportedMediaTypes(Collections.singletonList(MediaType.parseMediaType("application/pdf")));
        converters.add(bahHumbug);

        final MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        final ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        objectMapper.getFactory().configure(JsonGenerator.Feature.ESCAPE_NON_ASCII, true);
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        converter.setObjectMapper(objectMapper);
        converters.add(converter);
        super.configureMessageConverters(converters);
    }

Want to remove the null fields from the response. Please let me know if anything is wrong in the configuration.


Solution

  • Don't extend WebMvcConfigurationSupport as that is not equivalent to extending the deprecated WebMvcConfigurerAdapter.

    Instead implement WebMvcConfigurer which is also what is suggested in the deprecation documentation in the javadoc of `WebMvcConfigurerAdapter.

    Deprecated. as of 5.0 WebMvcConfigurer has default methods (made possible by a Java 8 baseline) and can be implemented directly without the need for this adapter

    So your configuration class header should look something like this

    @Configuration
    @EnableAspectJAutoProxy
    @EnableSwagger2
    @EnableWebMvc
    @PropertySource("classpath:test.properties")
    @ComponentScan(basePackages = {"com.test.web"})
    public class UmwWebConfig implements WebMvcConfigurer { ... }
    

    You need to add @EnableWebMvc again (as it should` and override/implement the interface method you need to use. In thise case probably only a single one.

    PRO-TIP: Use the Jackson2ObjectMapperBuilder to build the ObjectMapper and use the constructor of the MappingJackson2HttpMessageConverter. This saves creating an additional ObjectMapper (which happens in the default constructor).

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
            ByteArrayHttpMessageConverter bahHumbug = new ByteArrayHttpMessageConverter();
            bahHumbug.setSupportedMediaTypes(Collections.singletonList(MediaType.parseMediaType("application/pdf")));
            converters.add(bahHumbug);
    
            final ObjectMapper objectMapper = 
              Jackson2ObjectMapperBuilder.json()
                .serializationInclusion(JsonInclude.Include.NON_NULL)
                .failOnUnknownProperties(true)
                .featuresToEnable(JsonGenerator.Feature.ESCAPE_NON_ASCII)
                .build();       
    
            converters.add(new MappingJackson2HttpMessageConverter(objectMapper);
            super.configureMessageConverters(converters);
        }