Spring MVC 3 @ModelAttribute Annotation Example

Monday, April 18th, 2011

Background

So, I’m working on an existing Spring 3.x web project. This project heavily favours the use of annotations over XML configuration files. As I was trawling through the source code I noticed the “@ModelAttribute” annotation (which of course I had to look up!).

If the above background seems familiar that’s because it’s the same as for a previous Spring Annotation post I made (ed: this is in danger of turning into a mini-series)

Description

Most of the following is based upon the excellent Spring Documentation. I’ve simply lifted and rewritten the parts I require to serve as an “aide-mémoire”.

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

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();
    }
    // @RequestMapping etc omitted for brevity
}

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";
        }
    }
}

In the above example “myProduct” is populated with the corresponding value from the Model.

You can leave a response, or trackback from your own site.

Tags: , ,
Posted in: Spring



12 Responses to “Spring MVC 3 @ModelAttribute Annotation Example”

  1. HR Says:

    July 19th, 2011 at 10:29 pm

    Hi,

    thanks… was wondering about that annotation as well.. yuou just saved me a few hours 🙂

    I still have problems with understanding the use on the return value.. any input?


    @RequestMapping(value="/person/search", method=RequestMethod.GET)
    public @ModelAttribute(SEARCH_MODEL_KEY) Collection search() {
    return personDao.findPersons();
    }

  2. HR Says:

    July 19th, 2011 at 10:30 pm

    ups.. forgot the static def:


    private static final String SEARCH_MODEL_KEY = "persons";

  3. HR Says:

    July 21st, 2011 at 9:45 am

    cause as far as I can detect the following code(moved annotation to method level):


    @RequestMapping(value="/person/search", method=RequestMethod.GET)
    @ModelAttribute(SEARCH_MODEL_KEY)
    public Collection search() {
    return personDao.findPersons();
    }

    will render just the same?

  4. Shah Says:

    March 12th, 2012 at 6:33 am

    alert(“Thank you so much”);

  5. Shah Says:

    March 12th, 2012 at 6:34 am

    Its the most simple explination

  6. alenka Says:

    May 5th, 2012 at 7:53 am

    If we have several @ModelAttribute annotated methods, what order @ModelAttribute annotated methods will be called??

  7. lawrence Says:

    May 5th, 2012 at 8:01 am

    I believe that the ModelAttributes are pulled from from a Map and therefore the order that the methods are executed in cannot be relied upon. I’d be interested to hear your findings tho 🙂

  8. Ashu Says:

    June 20th, 2012 at 2:24 pm

    Hi,

    In my controller I have following function

    @ModelAttribute("ABeanCV")
    public AClass getCommand_Class()
    {
    AClass ABean=new AClass();
    ABean.setQuestions(new AutoPopulatingList(ABean.class));
    return ABean;
    }

    @RequestMapping(method = RequestMethod.GET, value="/AFormCV.htm")
    protected String showNameForm(@ModelAttribute("ABeanCV") AClass command_Class,ModelMap model)
    {
    command_Class.getQuestions().get(52).setAns("123456789");
    command_Class.getQuestions().get(52).setPrevAns("987654321");
    model.addAttribute("Question",as);
    command_Class.getQuestions().get(52).setCurrAns("435678543");
    model.addAttribute("Question",as);
    return "ACV";
    }

    @RequestMapping(method = RequestMethod.POST, value="/submitQuestionForm.htm")
    protected String submitNameForm(@ModelAttribute("ABeanCV") AClass commandClassCV, ModelMap model )
    {
    System.out.println("Ans wer to q 52 : "+commandClassCV.getQuestions().get(52).getAns());
    System.out.println("PREv Ans wer to q 52 : "+commandClassCV.getQuestions().get(52).getPrevAns());
    System.out.println("PREv Ans wer to q 52 : "+commandClassCV.getQuestions().get(52).getCurrAns());
    model.addAttribute("Question",as);
    return "ACV";
    }

    My JSP


    When I run the project in the form 2 fileds are displayed fine. After the form is submited when I try and print the 3 values in my submitNameForm function only those values get printed which are displayed on the form ie. " ans and prevAns ". The third value " currAns " whch was set in the showNameForm function prints null.

    Is the modelAttribute getting overwritten when the form is submitted? How can I still get the value of " currAns " ?

    Any help will be greatly appreciated.

  9. Ashu Says:

    June 20th, 2012 at 2:26 pm

    My JSP


    No idea why it dint get saved in the previous comment.

  10. Ashu Says:

    June 20th, 2012 at 2:26 pm

    Hi,

    In my controller I have following function

    @ModelAttribute("ABeanCV")
    public AClass getCommand_Class()
    {
    AClass ABean=new AClass();
    ABean.setQuestions(new AutoPopulatingList(ABean.class));
    return ABean;
    }

    @RequestMapping(method = RequestMethod.GET, value="/AFormCV.htm")
    protected String showNameForm(@ModelAttribute("ABeanCV") AClass command_Class,ModelMap model)
    {
    command_Class.getQuestions().get(52).setAns("123456789");
    command_Class.getQuestions().get(52).setPrevAns("987654321");
    model.addAttribute("Question",as);
    command_Class.getQuestions().get(52).setCurrAns("435678543");
    model.addAttribute("Question",as);
    return "ACV";
    }

    My JSP

    here I have only 2 input values " ans and prevAns " but in my showNameForm function I am setting values for " ans , prevAns and currAns " input values

  11. Isabel Marant Sneakers Says:

    October 18th, 2013 at 4:06 am

    I’m amazed, I have to admit. Seldom do I come
    across a blog that’s equally educative and interesting, and let
    me tell you, you’ve hit the nail on the head.

    The problem is an issue that not enough folks are speaking intelligently about.

    I’m very happy I came across this in my hunt for something regarding
    this.

  12. Spring Annotations | HelpEzee Says:

    January 15th, 2015 at 6:11 am

    […] http://lstierneyltd.com/blog/development/examples/spring-examples/spring-mvc-3-modelattribute-annota… […]

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>