Customizing SpringMVC Jackson Behaviors
These days it seems almost all examples of doing anything with Spring assume Spring Boot, which we’re not using. So here’s my foray into modifying the Jackson ObjectMapper
that SpringMVC configures and customizes by default.
Namely, I wanted to revert to the Jackson default of throwing an error on any incoming JSON requests to my API that have fields I don’t recognize. For some reason, Spring MVC changes this default.
After some Stack Overflow searches (again, almost entirely addressing how to do this with Spring Boot), and fiddling with some code in a debugger, I eventually figured out the simple solution of:
- Replacing my XML
<mvc:annotation-driven/>
with annotation@EnableWebMvc
on an@Configuration
class - Adding the following code to that class:
/** * To override any SpringMVC defaults */ @EnableWebMvc @Configuration public class CustomWebConfiguration implements WebMvcConfigurer { @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; } } } }
I had no success trying to get the ObjectMapper
instance and calling its enable()
method from XML, and apparently you can’t mix and match the XML <mvc:annotation-driven/>
with this Java Configuration object. But fortunately I was already doing the rest of my MVC Spring setup via annotations, using only <context:component-scan />
to kick it off.
(Yet another topic, we use XML configuration for the vast majority of our code, for a few reasons. First, historical and existing shared code. Second, I like having all the configuration in just few places rather than spread out all over the code. Third, I try to keep Spring-specific references out of any code that doesn’t already depend on Spring. Thus, we do use Spring annotations in our Controller classes, which are, by definition, dependent on Spring MVC.)