Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring MVC @ModelAttribute method

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";
}   
like image 449
Kamal Kishore Avatar asked Jul 29 '14 08:07

Kamal Kishore


People also ask

Can we map a request with @ModelAttribute?

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.

Can we use @ModelAttribute as a method argument?

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.

What is the difference between @ModelAttribute and @RequestBody?

@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.

What is @ModelAttribute in Spring MVC?

@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.


2 Answers

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.

like image 149
Ankur Singhal Avatar answered Nov 04 '22 10:11

Ankur Singhal


One is not better then the other. They both serve another purpose.

  • Method: If you need the model for a particular controller to be always populated with certain attributes the method level @ModelAttribute makes more sense.
  • Parameter: Use it on a parameter when you want to bind data from the request and add it to the model implicitly.

To answer your question on the better approach

I would say approach 2 is better since the data is specific to that handler.

like image 29
Bart Avatar answered Nov 04 '22 10:11

Bart