Question about Spring MVC
@ModelAttribute
methods, Setting model attributes in a controller @RequestMapping
method verses setting attribute individually with @ModelAttribute
methods, which one is considered better and is more used?
From design point of view which approach is considered better from the following:
Approach 1
@ModelAttribute("message")
public String addMessage(@PathVariable("userName") String userName, ModelMap model) {
LOGGER.info("addMessage - " + userName);
return "Spring 3 MVC Hello World - " + userName;
}
@RequestMapping(value="/welcome/{userName}", method = RequestMethod.GET)
public String printWelcome(@PathVariable("userName") String userName, ModelMap model) {
LOGGER.info("printWelcome - " + userName);
return "hello";
}
Approach 2
@RequestMapping(value="/welcome/{userName}", method = RequestMethod.GET)
public String printWelcome(@PathVariable("userName") String userName, ModelMap model) {
LOGGER.info("printWelcome - " + userName);
model.addAttribute("message", "Spring 3 MVC Hello World - " + userName);
return "hello";
}
Method level ModelAttribute annotation cannot be mapped directly with any request. Let's take a look at the following example for better understanding. We have 2 different methods in the above example.
An @ModelAttribute on a method argument indicates the argument should be retrieved from the model. So in this case we expect that we have in the Model person object as key and we want to get its value and put it to the method argument Person person.
@ModelAttribute is used for binding data from request param (in key value pairs), but @RequestBody is used for binding data from whole body of the request like POST,PUT.. request types which contains other format like json, xml.
@ModelAttribute is an annotation that binds a method parameter or method return value to a named model attribute, and then exposes it to a web view. In this tutorial, we'll demonstrate the usability and functionality of this annotation through a common concept, a form submitted from a company's employee.
The @ModelAttribute annotation
serves two purposes depending on how it is used:
At Method level
Use @ModelAttribute
at the method level to provide reference data for the model. @ModelAttribute annotated methods are executed before the chosen @RequestMapping
annotated handler method. They effectively pre-populate the implicit model with specific attributes, often loaded from a database. Such an attribute can then already be accessed through @ModelAttribute
annotated handler method parameters in the chosen handler method, potentially with binding and validation applied to it.
In other words; a method annotated with @ModelAttribute
will populate the specified “key” in the model. This happens BEFORE the @RequestMapping
At Method Parameter level
At Method Parameter level
When you place @ModelAttribute
on a method parameter, @ModelAttribute
maps a model attribute to the specific, annotated method parameter. This is how the controller gets a reference to the object holding the data entered in the form.
Examples
Method Level
@Controller
public class MyController {
@ModelAttribute("productsList")
public Collection<Product> populateProducts() {
return this.productsService.getProducts();
}
}
So, in the above example, “productsList
” in the Model is populated before the the @RequestMapping
is performed.
Method parameter level
@Controller
public class MyController {
@RequestMapping(method = RequestMethod.POST)
public String processSubmit(@ModelAttribute("product") Product myProduct, BindingResult result, SessionStatus status) {
new ProductValidator().validate(myProduct, result);
if (result.hasErrors()) {
return "productForm";
}
else {
this.productsService.saveProduct(myProduct);
status.setComplete();
return "productSaved";
}
}
}
Look here for detailed information with examples.
One is not better then the other. They both serve another purpose.
@ModelAttribute
makes more sense.I would say approach 2 is better since the data is specific to that handler.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With