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,@modelattributeetc, 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