Spring MVC @ModelAttribute method
Asked Answered
F

2

16

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";
}   
Footy answered 29/7, 2014 at 8:57 Comment(0)
G
15

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.

Gregorygregrory answered 29/7, 2014 at 10:0 Comment(1)
Ok I see. So when the data is specific to handler approach-2 is better and when data is generic and could be used by multiple handlers within the controller, then approach-1 is better. Thank you so much.Footy
P
22

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.

Petronille answered 29/7, 2014 at 9:10 Comment(4)
Thanks for your quick answer. I have refined the question further, please provide your views.Footy
@KamalKishore Please have a look at my answer, link added.Petronille
Thanks for the link, it explains pretty well the flow for ModelAttribute. Am tempted to go through your other blogs as well.Footy
shouldn't your attention be @modelAttribute("productsList") in the processSubmit method?Kissner
G
15

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.

Gregorygregrory answered 29/7, 2014 at 10:0 Comment(1)
Ok I see. So when the data is specific to handler approach-2 is better and when data is generic and could be used by multiple handlers within the controller, then approach-1 is better. Thank you so much.Footy

© 2022 - 2024 — McMap. All rights reserved.