Request mapping with Spring MVC 3.1 is quite sophisticated, and lets you use quite a few neat tricks. The following are two particularly tricky bits that are not very straight-forward to get directly from the documentation:
Map to the root of the controller mapping
It is there in the documentation, but isn’t immediately clear.
Suppose you have a controller with a root @RequestMapping like so:
@Controller
@RequestMapping("/nationalparks")
public class NationalParksController {
@RequestMapping(value="/add", method = RequestMethod.GET)
public String newPark() {
...
}
@RequestMapping(value="/add", method = RequestMethod.POST)
public String savePark() {
...
}
}
To add a new National Park to the system you’ll hit the following URL: http://example.com/nationalparks/add. This is great – you get a verb to add a park etc. But how do you list the parks?
You don’t really want a URL that looks like this: http://example.com/nationalparks/list because it’s a bit lame. Ideally – you’d want something like this: http://example.com/nationalparks = but how do you achieve that when you have a controller-level @RequestMapping?
Here is how:
@Controller
@RequestMapping("/nationalparks")
public class NationalParksController {
@RequestMapping(value="/add", method = RequestMethod.GET)
public String newPark() {
...
}
@RequestMapping(value="/add", method = RequestMethod.POST)
public String savePark() {
...
}
//Add this for magic-list!
@RequestMapping(method = RequestMethod.GET)
public String list() {
...
}
}
A GET method that has no additional mapping is mapped to the root of the controller-mapping itself. Neat!
URI Template Patterns
Suppose you have a NationalParksController as above. It is easy enough to add the following mapping to the controller:
@RequestMapping( value = "/{id}", method = RequestMethod.GET)
public String view() {
...
}
This method maps to urls of the form http://example.com/nationalparks/45 – to display the details of National Park that has id=45.
Easy – and not too difficult. But how do you get a list of the various tramps inside this National Park? Ideally, I’d like a URL that looks like this: http://example.com/nationalparks/45/tramps – but the tramps are served from a different controller.
No fear! you can use the following on the tramps controller:
@Controller
@RequestMapping("/nationalparks/{parkId}/tramps")
public class TrampsController {
@RequestMapping( method = GET)
public String list(@PathVariable("parkId") Long parkId, Model model) {
..
//retrieve tramps and add them to model
return "/tramps/list";
}
}
The {parkId} is a URI template pattern. Using it on the controller’s @RequestMapping maps the controller to serve requests of the template /nationalparks/*/tramps. The {parkId} in the URI is available to the individual methods using the @PathVariable annotation on the method parameter.
If the parameter name is going to be the same as the URI variable, you can actually omit the naming in the method signature. So the following code is identical to the one above:
@Controller
@RequestMapping("/nationalparks/{parkId}/tramps")
public class TrampsController {
@RequestMapping( method = GET)
public String list(@PathVariable Long parkId, Model model) {
..
//retrieve tramps and add them to model
return "/tramps/list";
}
}

So what you are saying is /nationalparks will invoke the GET method list.
It looks like beginning 3.1 & if you have enabled the new features, then this default behavior won’t work; as per the doc. You will get a 404 : org.springframework.web.servlet.PageNotFound – No mapping found for HTTP request.
However, contact/list w/o method level mapping invokes the list() method.
@AJ – you are right. You always pay for goodies