Sunday, 30 September 2012

A Footnote on Accessing Request Parameters using Spring 3 MVC

I recently got a comment on my blog: Accessing Request Parameters using Spring 3 MVC, pointing out something that I didn’t know about Spring’s @RequestParam annotation. The comment, from salient1, went like this:

“Most of your examples don't actually require you to use the @RequestParam annotation. You could have just created a String parameter called uuid and Spring would still automap it for you. You only need the annotation if you want your variable be different than the name of the value passed in or you want to change the default value, etc. Otherwise, it's a waste of space. on Accessing Request Parameters using Spring 3 MVC

So, I took my original code and tried this out1 and, yes, he’s right. If the argument name is the same as the request parameter name, then Spring will automatically do the mapping for you without the need for the @RequestParm annotation. This means that my original code example:

  @RequestMapping(value = "/help/detail", method = RequestMethod.GET)
 
public String displaySomeHelpDetail(@RequestParam("uuid") String uuid, Model model) {
   
return "view.name";
 
}

...could be written like this:

  @RequestMapping(value = "/help/detail", method = RequestMethod.GET)
 
public String displaySomeHelpDetail(String uuid, Model model) {
   
return "view.name";
 
}

This doesn’t really come as a big surprise, after all, Spring automatically maps other request handler arguments, such as Model without you having to do anything, although I do have a couple of reservations on using this technique.

Firstly, my blog, Accessing Request Parameters using Spring 3 MVC, has had about 10,000 hits and salient1 is the only person to mention this fact. This means that either lots of people know about this technique and haven’t told me, or it there’re very few people who know about it. I’m guessing that it’s the latter case which it true. Therefore, if only 1 in 10,000 developers knows about this feature then you have to question whether it’s a good idea to use it, especially given that one of the aims of any good developer should be to write clear and maintainable code. My first example above, although more verbose and containing a redundant annotation, will be understood by more developers than my second more concise example. You could therefore argue that that my first example is more readable, understandable and therefore maintainable than the second.

Secondly, I had a quick trawl through the Spring documentation on this and couldn’t find this technique mentioned anywhere2. This means that it is probably an undocumented feature and it’s NEVER a good idea to use undocumented features. They can be changed or removed at anytime without anything being said by the developers. This means that your code will stop working without any explanation if you, for example in this case, upgraded your version of Spring.

On the other hand, you could use this little known technique to impress your more junior colleagues as it’s one of those little known facts3 that will make you appear to be your team’s super cool Spring guru.



1This was tested using Spring 3.1
2If anyone knows where it’s mentioned then please send me the link.
3If you have heard of this technique, please let me know.



3 comments:

Anonymous said...

I totally agree, the proposed solution may be more concise but it's a pain in the ass to read such a code. Instead reading a @RequestParam makes it obvious of what it is, and not some argument coming from an HandlerMethodArgumentResolver.

Cheers

Yogesh Gandhi said...

But the second approach (automapping technique) has much cleaner code....and if it is somewhere documented in spring, i am glad to see the automapping technique...

I don't really like to use RequestParam annotation, as I find it redundant... But I also agree to the fact that you have specified here... that using undocumented features might be risky... :)

Anonymous said...

From my experimentation if you leave off the @RequestParam then it does not become a required parameter anymore. This of course can be bad if the method expects that value to not be null.