How to customize Jackson in Spring MVC (not Spring Boot) application

446 Views Asked by At

Spring MVC 4.3.29 and Java 8 (current platform constraints), and mostly XML configuration, except for some Controller classes that are annotation-scanned.

In short, I want to get the ObjectMapper instance being used automatically by Spring JSON deserialization, and I want to set its FAIL_ON_UNKNOWN_PROPERTIES back to true.

I see several related questions, but all the examples seem to be Spring Boot and/or Java configuration. And none of the suggested @Autowired beans (Mapper, Builder, etc.) have any values at all in my WebSphere environment.

Hopefully I'm just missing some simple glue somewhere.

Edit: Bah, I thought I had it with this:

@Configuration
public class CustomWebConfiguration extends WebMvcConfigurerAdapter {

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

        for (HttpMessageConverter<?> converter : converters) {
            if (converter instanceof MappingJackson2HttpMessageConverter) {
                ((MappingJackson2HttpMessageConverter) converter).getObjectMapper().
                    enable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
                break;
            }
        }
    }
}

And with my debugger I can see that it is being hit and changing the expected flag. But when used, the behavior is not in effect. I no longer have any XML overrides in place, but I do still have the "master" <mvc:annotation-driven/> there. I wonder if those are confusing each other...

2

There are 2 best solutions below

1
On BEST ANSWER

Ok, yes, this works as long as it's combined with @EnableWebMvc rather than <mvc:annotation-driven/>:

@EnableWebMvc
@Configuration
public class CustomWebConfiguration extends WebMvcConfigurerAdapter {

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

        for (HttpMessageConverter<?> converter : converters) {
            if (converter instanceof MappingJackson2HttpMessageConverter) {
                ((MappingJackson2HttpMessageConverter) converter).getObjectMapper().
                    enable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
                break;
            }
        }
    }
}
0
On

This kind-of "works", but by completely replacing Spring's ObjectMapper, Which then loses any other customizations it has, which I really don't want to do.

From this answer:

<bean id="myObjectMapper" class="com.fasterxml.jackson.databind.ObjectMapper"/>

<mvc:annotation-driven>
    <mvc:message-converters>
        <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
            <property name="objectMapper" ref="myObjectMapper"/>
        </bean>
    </mvc:message-converters>
</mvc:annotation-driven>

And then I could @Autowired inject those objects and mess with them, but in this case I wouldn't need to because just a new default Jackson ObjectMapper actually restores the behavior I'm wanting.