I have a Spring mvc @RestController class where the method parameter is annotated with @RequestBody. Something like this:
@RestController
@RequestMapping("/features")
public class FeatureController {
@PostMapping
public Feature createFeature(@RequestBody Feature feature) {
......
}
}
My Feature
class has a private constructor built using a Builder
pattern. So I created HttpMessageConverter
called FeatureConverter
and registered it properly using extendMessageConverters
. The converter uses Jackson to parse the JSON and then uses Feature.Builder
to create an instance of Feature
.
My problem is that Spring registers an instance of MappingJackson2HttpMessageConverter
before my custom FeatureConverter
. As a result the parsing is attempted by MappingJackson2HttpMessageConverter
even before it can reach FeatureConverter
. Since the constructor is private so MappingJackson2HttpMessageConverter
fails.
My question is how do I change the order so that FeatureConverter
is asked before MappingJackson2HttpMessageConverter
. Is there a proper way of doing it?
Spring MVC WebMvcConfigurerAdapter
initialize HttpMessageConverters like that:
protected final List<HttpMessageConverter<?>> getMessageConverters() {
if (this.messageConverters == null) {
this.messageConverters = new ArrayList<HttpMessageConverter<?>>();
configureMessageConverters(this.messageConverters);
if (this.messageConverters.isEmpty()) {
addDefaultHttpMessageConverters(this.messageConverters);
}
extendMessageConverters(this.messageConverters);
}
return this.messageConverters;
}
See: Github - WebMvcConfigurationSupport
As you can see there is 3 method:
configureMessageConverters
, empty by default it's where you are suppose to add convertersaddDefaultHttpMessageConverters
, where as the name said will create all default converters, the default MappingJackson2HttpMessageConverter
is created there.extendMessageConverters
which as the documentation:Override this method to extend or modify the list of converters after it has been configured. This may be useful for example to allow default converters to be registered and then insert a custom converter through this method.
Is to use when you want to modify the list after having all the defaults converter added.
To answer your question, if you don't need defaults converters you just have to Override configureMessageConverters
and add it:
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(new FeatureConverter());
}
If you need them you can either copy-paste the addDefaultHttpMessageConverters
content and add it into configureMessageConverters
and play with the order of initialisation there (ugly solution).
Otherwise you can use extendMessageConverters
to add it after the default initialization and play with the order:
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(the_index_you_want, new FeatureConverter());
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With