This forum is now a read-only archive. All commenting, posting, registration services have been turned off. Those needing community support and/or wanting to ask questions should refer to the Tag/Forum map, and to http://spring.io/questions for a curated list of stackoverflow tags that Pivotal engineers, and the community, monitor.

Custom HandlerMethodArgumentResolver that uses messageConverters

Sep 28th, 2012, 09:08 AM

Hello
I want to share my experience creating custom HandlerMethodArgumentResolver that binds and validates json object received in request parameter in a same fashion as @RequestBody and @RequestPart work. I will omit explanation why I need it, but let's say I had no choice.

Please correct any false statements you would find.

Ok, here is the problem:
1)messageConverters availability: Although default resolvers receive messageConverters in the constructor, your custom resolver can't. This is because it's instance is created before RequestMappingHandlerAdapter that provides access to messageConverters and RequestMappingHandlerAdapter needs to know your resolver in it's creation time. If you try to add your resolver after RequestMappingHandlerAdapter is created, the only access is provided by HandlerMethodArgumentResolverComposite, that allows adding resolvers only at the end of the list. This is a real issue because the method parameter will get processed by "catch-all" resolvers, namely RequestParamMethodArgumentResolver, so you need to place your custom resolver higher in the list. The only remaining solution is to register your resolver without messageConverters and get converters on first invocation. In this scenario you can't extend any abstract resolver that receives messageConverters in constructor(for example AbstractMessageConverterMethodArgumentResolver)

2)HttpMessageConverter implemetation doesn't provide any way for reading serialized object from request parameter. They basicaly invoke HttpInputMessage.getBody() which works only for @RequestBody and @RequestPart.

Here is working implementation I produced after half day struggle, learning Spring internals on the way. For the most part it's customized copy/paste from existing resolvers. It's using beanFactory to get messageConverters on first invocation and creates fake HttpInputMessage with parameter content in the body to satisfy mesage converter. Cotent type is determine from custom annotation. I can't use content-type header itself, because I'm limited to "application/x-www-form-urlencoded". More convenient way would be to use a custom header to receive parameter content type from client application, but I don't need such implementation for now.

I would extend AbstractMessageConverterMethodArgumentResolver and override the method createInputMessage. Then return a ServletServerHttpRequest sub-class that can read the body from a request parameter. For example see how ServletServerHttpRequest already does something similar in its method getBodyFromServletRequestParameters.