简体   繁体   中英

How to configure MappingJacksonHttpMessageConverter while using spring annotation-based configuration?

I was unreasonable enough to went into configuring spring beans via annotations and not pure xml beans and now I'm facing the consequences.

I configure REST channels using

<mvc:annotation-driven />

Now I want simply configure the MappingJacksonHttpMessageConverter to output to JSON only this fields that have non-null values. I've tried the following:

<bean id="jsonHttpMessageConverter"
    class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
    <property name="prefixJson" value="false" />
    <property name="supportedMediaTypes" value="application/json" />
    <property name="objectMapper">
        <bean class="org.codehaus.jackson.map.ObjectMapper">
            <property name="serializationInclusion" value="NON_NULL"/>
        </bean>
    </property>
</bean>

The beans gets created, but another instance of converter is created and used in channels. So I've tried the way with @Configuration and @Bean described in this Stackoverflow question , but still json serialization uses its own configuration.

Finally I've tried to inject the mapper via

@Autowired
private MappingJacksonHttpMessageConverter jacksonConverter;

but I've ended with NoSuchBeanDefinitionException . So now I'm out of options and therefore I'm asking for any ideas here. How to controll and configure the mapper used by framework?

Use the WebMvcConfigurer.configureMessageConverters() method:

Configure the HttpMessageConverters to use [...] If no message converters are added to the list, default converters are added instead.

With @Configuration you have:

@Configuration
class MvcConf extends WebMvcConfigurationSupport {
    protected void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.add(converter());
        addDefaultHttpMessageConverters(converters);
    }

    @Bean
    MappingJacksonHttpMessageConverter converter() {
        MappingJacksonHttpMessageConverter converter = new MappingJacksonHttpMessageConverter()
        //do your customizations here...
        return converter;
    }
}

Call to addDefaultHttpMessageConverters() is required because the defaults are not applied when using custom converters.

IMPORTANT NOTE You must remove @EnableWebMvc for your converters to be configured if you extend WebMvcConfigurationSupport.

The customization of the spring mvc servlet configuration only in java code can be accomplished in multiple ways.

The simplest one seems to be extending your @Configuration annotated class with WebMvcConfigurerAdapter :

@Configuration
@EnableWebMvc
public class ApplicationSpringConfig extends WebMvcConfigurerAdapter {
    @Override
    public void configureMessageConverters( List<HttpMessageConverter<?>> converters ) {
        converters.add(converter());
    }

    @Bean
    MappingJackson2HttpMessageConverter converter() {
        // [...]
    }
}

Notice that this is lot like the example provided by the answer of Tomasz Nurkiewicz .

However using WebMvcConfigurationSupport instead of WebMvcConfigurerAdapter is more appropriate for Advanced Customizations. That was the case if you needed to also add the default converters.

See the Spring documentation Customizing the Provided Configuration

The following solution is for Spring 4.3, (non-boot) where it was necessary to address fetch=FetchType.LAZY by adding a module to the Jackson converters. A similar technique can be used to modify converters in any way, including removal and recreation.

@Configuration
@EnableWebMvc
public class MvcConfig extends WebMvcConfigurerAdapter {

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

    for (HttpMessageConverter<?> mc : converters){
         if (mc instanceof MappingJackson2HttpMessageConverter || mc instanceof MappingJackson2XmlHttpMessageConverter) {
            ((AbstractJackson2HttpMessageConverter) mc).getObjectMapper().registerModule(new Hibernate5Module());
        }
    }
    return;
 }

In this case,

  • the WebMvcConfigurerAdapter has a lot of other configuration in it and I wanted to avoid another configuration class.
  • Using extendMessageConverters enabled access to the automatically-configured Jackson classes without losing the configuration of all other message converters, which is what configureMessageConverters would have done.
  • Using registerModule you can simply add the needed Hibernate5Module to the existing converters.
  • The module was added to both the JSON and XML processors

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM