Handler Method Parameters
You can pass arguments to controller handler methods (methods with the
@RequestMapping annotation). Specifically, you can pass any argument of the type listed in Table 3 to a handler method without further annotation in the controller. The Spring container automatically locates the correct object and passes it as the proper argument.
Table 3. Types of Arguments You Can Pass to Handler Methods |
Parameter Type |
Description |
BindingResult |
Spring MVC BindingResult object (org.springframework.validation.BindingResult) |
Command Object |
Spring MVC-defined Command objects |
Errors |
Spring MVC Errors object (org.springframework.validation.Errors) |
InputStream/Reader |
Servlet API provided raw InputStream/Reader (java.io.InputStream or Reader) |
Locale |
Request locale (java.util.Locale) |
Map |
Map provided as Spring model to the view (java.util.Map) |
Model |
Map provided as Spring model to the view (org.springframework.ui.Model) |
ModelMap |
Map provided as Spring model to the view (org.springframework.ui.ModelMap) |
OutputStream/Writer |
Servlet API provided raw OutputStream/Writer (java.io.OutputStream or Writer) |
Request |
Servlet API Request object (use either HttpServletRequest or ServletRequest) |
Response |
Servlet API Response object (use either HttpServletRequest or ServletRequest) |
Session |
Servlet API Session object |
SessionStatus |
Spring provided handle for marking when form processing is finished (org.springframework.web.bind.support.SessionStatus) |
WebRequest |
Spring-provided objects for parameter and attribute access without the Servlet API (use org.springframework.web.context.request.WebRequest or NativeWebRequest) |
The Spring container automatically detects the parameter need and passes the appropriate object to the handler method. For example, the sayHello method here automatically gets passed the HttpServletRequest object.
@Controller
public class HelloWorldController {
@RequestMapping("/greeting.request")
protected String sayHello (HttpServletRequest req){
String name = req.getParameter("name");
return "greet";
}
}
Author's Note: When creating the handler methods, consider some of the ramifications of using certain parameter types. Using parameters such as Model or HttpServletRequest couples the controller to Spring, the Servlet API, or both. Part of the rationale for moving to the annotated controllers may be to remove or reduce such coupling. |
You can use the @RequestParam annotation, another of the Spring 2.5 MVC annotations, on a handler method to bind a request parameter to a method parameter. In the code example above, the "name" parameter is programmatically fetched out of the HttpServletRequest object. In the following example, the @RequestParam annotation accomplishes the same task more directly and automatically.
@Controller
public class HelloWorldController {
@RequestMapping("/greeting.request")
protected String sayHello (@RequestParam("name") String name){
return "greet";
}
}
By default, parameters annotated with @RequestParam are required method parameters. You can make a parameter optional by setting the required attribute of @RequestParam to false.
Similar to how @RequestParam binds a request parameter to a method parameter, the @ModelAttribute annotation can be used on a handler method parameter to bind a model object's attribute to a method parameter.
@RequestMapping("/displaycustomer.request")
public String show(@ModelAttribute("customer") Customer cust) {
...
return "displaycustomer";
}
The @ModelAttribute annotation also has a second use. You can use it to put information, such as reference data, into the model. When you place the @ModelAttribute annotation on a method, the method it annotates will get executed before the appropriate handler method. This has the effect of pre-populating the model.
Consider the HTML for a simple form entry page in Listing 1. The @ModelAttribute annotated method in the controller populates the "titles" options in the getname.jsp before the page displays.
@Controller
public class HelloWorldController {
@ModelAttribute("titles")
public List<String> populateTitles() {
String[] titles = { "Mr.", "Mrs.", "Miss", "Ms.", "Dr." };
return Arrays.asList(titles);
}
@RequestMapping(value="/greeting.request",method=RequestMethod.GET)
protected String showForm (){
return "getname";
}
@RequestMapping(value="/greeting.request",method=RequestMethod.POST)
protected String sayHello (@RequestParam(value="name") String name, @RequestParam(value="title") String title){
System.out.println("Yep name is: " + title + " " + name);
return "greet";
}
}
Handler Method Return Types
Handler methods can return almost any type of data. You can use the data returned as the model, view, or other such Spring MVC component depending on its type. Table 4 describes the types of data that a handler method can return and how the Spring container uses that data. Again, using a Spring type (like ModelAndView) as the return type of a handler method couples the controller to Spring. So use some return objects with caution.
Table 4. Types and Uses of Data That a Handler Method Can Return |
Return Data Type |
How the Return Data Is Used |
ModelAndView |
Used as any ModelAndView object would be used, as if returned by a handleRequest method of a non-annotated controller (org.springframework.web.servlet.ModelAndView) |
Model |
The Model object (of the ModelAndView) containing key-value pairs of model data (org.springframework.ui.Model) |
Map |
Key-value pair model data (java.util.Map) |
View |
The View object (of the ModelAndView) containing information on the logical view name (org.springframework.web.servlet.View) |
String |
Interpreted as the logical view name, as would be represented in a View object |
void |
Indicates that the handler method handles the response rendering itself, just as any handleRequest type method of a non-annotated controller |
other |
Any other return type gets treated as a single model attribute value accessed by the name specified in @ModelAttribute (if provided) or based on the return type class name (when @ModelAttribute is not used) |