Reputation: 5084
Hi i was wondering what is the purpose of using @ModelAttribute
why use
@RequestMapping(value="")
public String index(@ModelAttribute("before") Before b) {
System.out.println(b.getBeforeString());
return "home/index";
}
@ModelAttribute("before")
public Before before() {
return new Before();
}
when I can use
@RequestMapping(value="")
public String index() {
Before b = new Before();
System.out.println(b.getBeforeString());
return "home/index";
}
Upvotes: 0
Views: 571
Reputation: 3936
@ModelAttribute
is used to populate things into the MVC Model for subsequent use in the View. It is not the only way to put things in the model (this can be done directly by code aswell) but it is convenient way of adding @RequestMapping
method args, or the return value from a method, amongst other things.
Methods annotated with @ModelAttribute
are invoked PRIOR TO every @RequestMapping
method that is invoked in the same controller class. This is generally used for popuplating read-only components for a form - eg the values for a select list. (http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/htmlsingle/spring-framework-reference.html#mvc-ann-modelattrib-methods) - or for preparing beans prior binding incoming request values (eg loading from a datastore).
So, in your first example ...
@ModelAttribute("before")
public Before before() {
return new Before();
}
@RequestMapping(value="")
public String index(@ModelAttribute("before") Before b) {
System.out.println(b.getBeforeString());
return "home/index";
}
... the before()
method will be invoked first and put a Before
instance in the model with the name "before". Next the index(...)
method will be invoked and receive the very same Before
instance (because it also uses the model attribute name "before") - but it will now be populated with values from the request, where the request param names map to Before property names. (Aside: This is perhaps not what you are intending. If this is really what you want you should consider adding a BindingResult
as second arg to the index method to catch any binding errors (http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/htmlsingle/spring-framework-reference.html#mvc-ann-arguments bullet point 17)).
Following this, the @ModelAttribute
anntotation in index(...)
will also cause that Before
instance to be present the model with the name "before" for use in the next view: "/home/index".
(It's worth noting: If you did not have the before()
method at all, your index()
method would recieve an instance of Before
created with its no-arg constructor and then popuplated with the incoming request values. It would still subsequently put it in the model with the name "before" for use by the next view.)
Your second code snippet ...
@RequestMapping(value="")
public String index() {
Before b = new Before();
System.out.println(b.getBeforeString());
return "home/index";
}
... is not actually adding the Before
to the model at all, so it wont be available in the view. If you want Before in the model here use:
@RequestMapping(value="")
public String index(Model uiModel) {
Before b = new Before();
System.out.println(b.getBeforeString());
uiModel.addAttribute("beforeName", b); // will add to model with name "beforeName"
uiModel.addAttribute(b) // will add to model with a default name (lower-cased simple type name by convention), ie: "before"
return "home/index";
}
HTH
Upvotes: 3