What is @ModelAttribute in Spring MVC?

So I will try to explain it in simpler way. Let's have:

public class Person {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(final String name) {
        this.name = name;
    }
}

As described in the Spring MVC documentation - the @ModelAttribute annotation can be used on methods or on method arguments. And of course we can have both use at the same time in one controller.

1.Method annotation

@ModelAttribute(“cities”)
 public List<String> checkOptions(){
 return new Arrays.asList(new[]{“Sofia”,”Pleven","Ruse”});//and so on
}

Purpose of such method is to add attribute in the model. So in our case cities key will have the list new Arras.asList(new[]{“Sofia”,”Pleven","Ruse”}) as value in the Model (you can think of Model as map(key:value)). @ModelAttribute methods in a controller are invoked before @RequestMapping methods, within the same controller.

Here we want to add to the Model common information which will be used in the form to display to the user. For example it can be used to fill a HTML select:

enter image description here

2.Method argument

public String findPerson(@ModelAttriute(value="person") Person person) {
    //..Some logic with person
    return "person.jsp";
}

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. If such does not exists or (sometimes you misspell the (value="persson")) then Spring will not find it in the Model and will create empty Person object using its defaults. Then will take the request parameters and try to data bind them in the Person object using their names.

name="Dmitrij"&countries=Lesoto&sponsor.organization="SilkRoad"&authorizedFunds=&authorizedHours=&

So we have name and it will be bind to Person.name using setName(String name). So in

//..Some logic with person

we have access to this filled name with value "Dimitrij".

Of course Spring can bind more complex objects like Lists, Maps, List of Sets of Maps and so on but behind the scene it makes the data binding magic.

  1. We can have at the same time model annotated method and request method handler with @ModelAttribute in the arguments. Then we have to union the rules.

  2. Of course we have tons of different situations - @ModelAttribute methods can also be defined in an @ControllerAdvice and so on...


For my style, I always use @ModelAttribute to catch object from spring form jsp. for example, I design form on jsp page, that form exist with commandName

<form:form commandName="Book" action="" methon="post">
      <form:input type="text" path="title"></form:input>
</form:form>

and I catch the object on controller with follow code

public String controllerPost(@ModelAttribute("Book") Book book)

and every field name of book must be match with path in sub-element of form


I know this is an old thread, but I thought I throw my hat in the ring and see if I can muddy the water a little bit more :)

I found my initial struggle to understand @ModelAttribute was a result of Spring's decision to combine several annotations into one. It became clearer once I split it into several smaller annotations:

For parameter annotations, think of @ModelAttribute as the equivalent of @Autowired + @Qualifier i.e. it tries to retrieve a bean with the given name from the Spring managed model. If the named bean is not found, instead of throwing an error or returning null, it implicitly takes on the role of @Bean i.e. Create a new instance using the default constructor and add the bean to the model.

For method annotations, think of @ModelAttribute as the equivalent of @Bean + @Before, i.e. it puts the bean constructed by user's code in the model and it's always called before a request handling method.

Figuratively, I see @ModelAttribute as the following (please don't take it literally!!):

@Bean("person")
@Before
public Person createPerson(){
  return new Person();
}

@RequestMapping(...)
public xxx handlePersonRequest( (@Autowired @Qualifier("person") | @Bean("person")) Person person, xxx){
  ...
}

As you can see, Spring made the right decision to make @ModelAttribute an all-encompassing annotation; no one wants to see an annotation smorgasbord.


@ModelAttribute refers to a property of the Model object (the M in MVC ;) so let's say we have a form with a form backing object that is called "Person" Then you can have Spring MVC supply this object to a Controller method by using the @ModelAttribute annotation:

public String processForm(@ModelAttribute("person") Person person){
    person.getStuff();
}

On the other hand the annotation is used to define objects which should be part of a Model. So if you want to have a Person object referenced in the Model you can use the following method:

@ModelAttribute("person")
public Person getPerson(){
    return new Person();
}

This annotated method will allow access to the Person object in your View, since it gets automatically added to the Models by Spring.

See "Using @ModelAttribute".