3

I'm trying to deserialize some JSON with Jackson in Spring. I have configured it to use a custom MappingJackson2HttpMessageConverter and I can see it gets registered. Still, when trying to deserialize, I see that it is not using my custom MappingJackson2HttpMessageConverter but that instead it uses the defaultList of HttpMessageConverters (in other words it's not overridden). Any idea how it could be solved ? Thanks.

package com.bigid.scanner.service.restapi;

import com.bigid.scanner.api.datalink.DataLink;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

import java.text.SimpleDateFormat;
import java.util.List;

@Configuration
@EnableWebMvc
public class WebConfiguration extends WebMvcConfigurerAdapter {

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        super.configureMessageConverters(converters);
        Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
        builder.mixIn(DataLink.class, PolymorphicDataLinkMixin.class);
        converters.add(new MappingJackson2HttpMessageConverter(builder.build()));
    }
}
jhagege
  • 1,486
  • 3
  • 22
  • 36

4 Answers4

2

Many of these answers look good. In addition, if you are using Spring Boot, be sure you don't have the @EnableWebMvc annotation on your configuration. I spent many hours trying numerous different ways (some of which are documented in the questions and responses here) to register/configure custom Jackson Serializers and Deserializers, none of which were working correctly. While debugging I could see the registration code was being invoked on application startup, yet the De/Serializers were never called. Apparently the @EnableWebMvc was overriding these registrations in the Spring Boot environment. Simply removing this annotation made everything work just as expected.

rscarter
  • 227
  • 4
  • 11
  • 1
    For reference here is some more detailed explanation https://stackoverflow.com/questions/51008382/why-spring-boot-application-doesnt-require-enablewebmvc – lujop Sep 23 '21 at 07:17
0

I think you should call super.configureMessageConverters(converters); at the end of the overridden configureMessageConvertersor do not call it at all and provide the other default converters.

Try 1

@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {

    Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
    builder.mixIn(DataLink.class, PolymorphicDataLinkMixin.class);
    converters.add(new MappingJackson2HttpMessageConverter(builder.build()));

    super.configureMessageConverters(converters);
}

Try 2 (not calling super.configureMessageConverters)

@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {

    Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
    builder.mixIn(DataLink.class, PolymorphicDataLinkMixin.class);
    converters.add(new MappingJackson2HttpMessageConverter(builder.build()));

    super.addDefaultHttpMessageConverters();
}
pleft
  • 7,567
  • 2
  • 21
  • 45
0
@Configuration
@EnableWebMvc
public class WebConfiguration extends WebMvcConfigurerAdapter {

        protected void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
            converters.add(converter());
            addDefaultHttpMessageConverters(converters);
        }

        @Bean
        MappingJacksonHttpMessageConverter converter() {
            MappingJacksonHttpMessageConverter converter = new MappingJacksonHttpMessageConverter()
            //do your customizations here...
            return converter;
        }
    }
biology.info
  • 3,500
  • 2
  • 28
  • 39
0

Thanks for your help.

Problem was I had <mvc: annotation-driven> inside the web.xml file. Because of that, the messageConverters would get registered two times:

  • Once with the default messageConverters (9 in total)
  • Once by my code which would register only one.

While processing values with @RequestBody, they would get serialized by the default one (9 messageConverters) and not by mine (not sure if this is random behavior, but any case it would have unexpected results).

Hope it helps someone !

jhagege
  • 1,486
  • 3
  • 22
  • 36