You can use the @ModelAttribute annotation:

  • As a method argument in methods with the @RequestMapping annotation to create or access an object from the model and bind it to a request via WebDataBinder.

  • As a method-level annotation in classes marked with @Controller or @ControllerAdvice annotations that helps initialize the model before calling a method with the @RequestMapping annotation.

  • For the @RequestMapping method to indicate that its return value is a model attribute.

This section covers methods, the @ModelAttribute annotation is the second item in the previous list. A controller can have any number of methods marked with the @ModelAttribute annotation. All such methods are called before methods with the @RequestMapping annotation in the same controller. A method annotated with @ModelAttribute can also be shared between controllers via the @ControllerAdvice annotation.

Methods with the @ModelAttribute annotation have flexible method signatures. They support many of the same arguments as methods marked with the @RequestMapping annotation, except for the @ModelAttribute annotation itself or anything associated with the request body.

The following example shows a method annotated with @ModelAttribute:

Java
@ModelAttribute
public void populateModel(@RequestParam String number, Model model) {
    model.addAttribute(accountRepository.findAccount(number));
    // add more...
}
Kotlin
@ModelAttribute
fun populateModel(@RequestParam number: String, model: Model) {
    model.addAttribute(accountRepository.findAccount(number))
    // add more...
}

The following example adds only one attribute:

Java
@ModelAttribute
public Account addAccount(@RequestParam String number) {
    return accountRepository.findAccount(number);
}
Kotlin
@ModelAttribute
fun addAccount(@RequestParam number: String): Account {
    return accountRepository.findAccount(number)
}
If the name is not specified explicitly, then the default name is chosen based on the Object type, as explained in the javadoc at Conventions. You can always assign an explicit name using the addAttribute overload or through the name attribute in the @ModelAttribute annotation (for the return value).

You can also use the @ModelAttribute annotation as a method-level annotation for methods annotated with @RequestMapping, in which case the return value of the method annotated with @RequestMapping will be interpreted as a model attribute. This is usually not required as it is the default operating logic in HTML controllers, unless the return value is a String, which would otherwise be interpreted as the name of the view. The @ModelAttribute annotation can also customize the model attribute name, as shown in the following example:

Java
@GetMapping("/accounts/{id}")
@ModelAttribute("myAccount")
public Account handle() {
    // ...
    return account;
}
Kotlin
@GetMapping("/accounts/{id}")
@ModelAttribute("myAccount")
fun handle(): Account {
    // ...
    return account
}