0

I have been using the following code:

@RequestMapping(value="/myUrl", method=RequestMethod.GET)
public ModelAndView myRequestHandler(
    HttpServletRequest request, HttpServletResponse response,
    @ModelAttribute(value="paramName") @ValidMyModelForm form)
// automatically populates form setters from form:form in JSP view
{
}

Reading the answers at the following link I am starting to doubt that my usage of ModelAttribute is not correct here.

What is @ModelAttribute in Spring MVC?

Am I using it the right way? It seems to work but want to make sure I am not doing anything wrong.

The form object is added to model in a separate method using code that looks like:

 modelAndView.addObject("formName", new MyModelForm());

In the JSP view I have a the forms name added as the commandName="formName".

Community
  • 1
  • 1
Rohit Banga
  • 18,458
  • 31
  • 113
  • 191
  • 1
    The only way to make sure if you are doing something wrong or not is to try it. – Sotirios Delimanolis Mar 20 '13 at 23:31
  • Oh it has been working fine for me so far ... but i want to check if I am abusing the fact that a new bean is created and the setters are called when an autowired bean has the same name as my model attribute. Although it works I want to understand if it is working just by chance and if so is there a more "standard way" to use form:form in spring? – Rohit Banga Mar 20 '13 at 23:54
  • The explanation in the linked question is causing me to rethink about this way of coding it. – Rohit Banga Mar 20 '13 at 23:56

1 Answers1

0

This signature also should have worked perfectly for you:

public ModelAndView myRequestHandler(@Valid MyModelForm form)

here Spring MVC will ensure that a MyModelForm instance is created and bound based on what is submitted from your form.

Now, what does additional @ModelAttribute bring you:

First the simple case:

public ModelAndView myRequestHandler(@ModelAttribute("paramName") @Valid MyModelForm form)

Assuming you do not have any other method with @ModelAttribute, what the above will do is look for a model by name paramName, which is not likely to be present because of the assumption, then an instance of MyModelForm will be created and bound just like before, with one addition that you now have a model object with name paramName available that you can use in your view: paramName.myformValue etc..

So in essence:

public ModelAndView myRequestHandler(@ModelAttribute("paramName") @Valid MyModelForm form)

is equivalent to:

public ModelAndView myRequestHandler(@Valid MyModelForm form, Model model) {
    ...
    model.addAttribute("paramName", form)
}

Secondly, if you had a method annotated with @ModelAttribute which preloads say part of your MyModelForm:

@ModelAttribute("paramName");
public MyModelForm loadModel(int id) {
   MyModelForm fromDB = loadFromDB(id);
}

Now, the advantage of your method signature:

public ModelAndView myRequestHandler(@ModelAttribute("paramName") @Valid MyModelForm form)

will be that the model that you have pre-populated from your DB, will be enhanced with what is submitted in the form.

Biju Kunjummen
  • 49,138
  • 14
  • 112
  • 125
  • I see ... Since you say advantage ... does that mean it is preferred/only way of connecting spring `` tags in JSP and models. – Rohit Banga Mar 21 '13 at 01:40
  • Since the model will be enhanced with what I have submitted in the form, I hope it is just my copy of the form and not the DB's copy of data that gets modified automatically. I want to do some checks on the model form which decorates a JPA entity. – Rohit Banga Mar 21 '13 at 01:46
  • Thinking about my question ... I think if I call merge at some point of time with the entity as the argument only then the changes should be sent to the database. Also this reasoning depends on the fact that every time I fetch a form using ajax I create a new ModelForm with new ModelEntity() in the constructor of the model form. The user populates all fields except the primary key field and submits the form. I set the primary key field based on some other parameters in the form. I guess it should be fine as long as I do not call merge. – Rohit Banga Mar 21 '13 at 02:26