views:

7922

answers:

1

I have a Spring 2.5 annotated Controller in which I have a method annotated with @RequestMapping(method=RequestMethod.GET), which performs some logic to fill the model.

I also have a method annotated with @RequestMapping(method=RequestMethod.POST) which performs the request. This method has a @ModelAttribute annotated parameter that contains my own form pojo, let's call it MyForm. I also have an initialization method for MyForm, also annotated with @ModelAttrribute. Now so far all works as expected: on a POST request the form data binds to MyForm and I can process it.

The problem is that I want to be able to pre-populate the form by passing in (GET) request parameters. Since I have the @ModelAttribute method for MyForm, I do get a MyForm instance in my model, but it doesn't get populated unless I specifically use it as a parameter for my GET method.

Why do I have to do this, is it possible to force data binding on my form for a GET request in a different way? I now just pass in the parameter, but because it is already in the model I don't have to do anything with it, resulting in an ugly unused method parameter.

[Edit: some code examples to illustrate]

The controller that doesn't populate the form on a get request:

@Controller
public class MyController {

  @ModelAttribute("myForm")
  public MyForm createForm() {
    return new MyForm();
  }

  @RequestMapping(method=RequestMethod.GET)
  public void handlePage(Model model) {
    //Do some stuff to populate the model....
  }

  @RequestMapping(method=RequestMethod.POST)
  public void processForm(@ModelAttribute("myForm") MyForm myForm) {
    //Process the form
  }
}

When I change the method signature of the handlePage method, it gets populated on a get request...

@RequestMapping(method=RequestMethod.GET)
public void handlePage(Model model, @ModelAttribute("myForm") MyForm myForm) {
  //Do some stuff to populate the model....
}
+2  A: 

The method with the @ModelAttribute is allowed to have any arguments that @RequestMapping supports, so for example you could add how ever many @RequestParam arguments as needed to populate your command object, or even the http request itself. I'm not sure if you can get an instance of the data binder in that same manner or not.

Reading the docs again I think the idea is that the pre-population in the @ModelAttribute method would be database driven, which is probably why there isn't any data binding happening without adding the @ModelAttribute as an argument to the @RequestMapping method.

Corey
No, the data binder is only available in an @InitBinder annotated method. I thought of that too... to bad it doesn't work :(Now I just "fixed" it by passing in the model attribute and annotating it with @SuppressWarnings("unused").
Jaap Coomans