java - Spring MVC: Is it possible to bind a specific HttpMessageConverter to a @RequestBody-annotated parameter? -
i have spring boot application default abstractjackson2httpmessageconverter
. bound jackson objectmapper
instance has custom simplemodule
registered supports multimap
google guava library.
@bean public objectmapper objectmapper() { return new objectmapper() .setserializationinclusion(non_null) .configure(fail_on_unknown_properties, false) .registermodule(new simplemodule() .addserializer(multimaptype, multimapduplicatekeysserializer) .adddeserializer(multimaptype, multimapjsondeserializer) ); }
and suppose have following method in controller:
@requestmapping(method = post) @responsestatus(ok) public object post( @requestbody final multimap<string, object> multimap ) { ... }
at step fine. have validate multimap empty or blank keys, , return http 400 if there invalid keys found in incoming multimap. trivial operation , can done traversing incoming multimap , throwing exception handled in controller advice. has @ least next flaws:
- i don't want validate multimaps directly somewhere in controller or associated service.
- if it's flaw: couldn't make work spring mvc annotations
@valid
,@modelattribute
etc, don't care these, because of following: - i don't want multimap validated after it's deserialized, because validate incoming request body @ parser level somewhere in specific
httpmessageconverter
-- validation need purely json stream validation work big multimaps not requiring whole multimap deserialized before validation. if possible, of course.
is possible bind specific httpmessageconverter
specific @requestbody
only? like:
@requestmapping(method = post) @responsestatus(ok) public object post( @somemagicspringannotationhere("specifichttpmessageconverter") @requestbody final multimap<string, object> multimap or @anothermagicspringannotationhere("specificobjectmapper") @requestbody final multimap<string, object> multimap or @whatevermagicspringannotationhere @requestbody final multimap<string, object> multimap ) { ... }
or wrong approach , can accomplished more spring-related , more elegant? suggestions appreciated. in advance!
create specialized annoation i.e @multimaprequestbody
@target(elementtype.parameter) @retention(retentionpolicy.runtime) @documented public @interface multimaprequestbody { boolean required() default true;
then create multimaprequestbodymethodargumentresolver
knows do.
public class multimaprequestbodymethodargumentresolver implements handlermethodargumentresolver { public boolean supportsparameter(methodparameter parameter) { return parameter.hasparameterannotation(multimaprequestbody.class); // maybe check argument type too. } public object resolveargument(methodparameter parameter, modelandviewcontainer mavcontainer, nativewebrequest webrequest, webdatabinderfactory binderfactory) throws exception { // logic validation , converting using jackson // take @ mappingjackson2httpmessageconverter } }
now can handle body conversion , validation yourself. might want take @ mappingjackson2httpmessageconverter
inspiration on how read , parse body. or maybe extend 1 of abstract
classes used argument conversion.
now in request handling method use @multimaprequestbody
instead of @requestbody
annotation.
@requestmapping(method = post) @responsestatus(ok) public object post( @multimaprequestbody final multimap<string, object> multimap ) { ... }
Comments
Post a Comment