Andrei Pall

Linux Software Engineering

ModelAttribute in Spring MVC

In Spring MVC, @ModelAttribute is mainly used to bind HTTP request parameters to a Java object (a model/DTO) and/or add an object to the MVC model.

Think of it as:

Request parameters → Java object → Controller

1. Binding form data to a Java object

Suppose you have a form:

<form action="/register" method="post">
    <input name="name">
    <input name="email">
    <input name="age">
    <button type="submit">Register</button>
</form>

And a Java class:

public class User {
    private String name;
    private String email;
    private int age;

    // getters and setters
}

Your controller can use:

@PostMapping("/register")
public String register(@ModelAttribute User user) {
    System.out.println(user.getName());
    System.out.println(user.getEmail());
    System.out.println(user.getAge());

    return "success";
}

Spring automatically:

  1. Creates a User object.
  2. Reads request parameters (name, email, age).
  3. Matches them to the object’s properties.
  4. Calls the setters.
  5. Passes the populated object to your method.

So if the request is:

POST /register
name=John&email=john@example.com&age=25

Spring effectively creates:

User user = new User();
user.setName("John");
user.setEmail("john@example.com");
user.setAge(25);

2. @ModelAttribute with GET request parameters

It isn’t limited to HTML forms.

For example:

/products?name=laptop&category=electronics

You could write:

@GetMapping("/products")
public String products(@ModelAttribute ProductFilter filter) {
    // filter.name = "laptop"
    // filter.category = "electronics"

    return "products";
}

This is useful when you have multiple related request parameters.

Instead of:

@GetMapping("/products")
public String products(
        @RequestParam String name,
        @RequestParam String category,
        @RequestParam int page) {
    ...
}

you can group them:

public String products(@ModelAttribute ProductFilter filter)

3. Adding an object to the Model

@ModelAttribute can also be used on a method:

@ModelAttribute
public User createUser() {
    return new User();
}

This makes the returned object available in the MVC model for controller methods/views.

For example:

@Controller
public class UserController {

    @ModelAttribute
    public User user() {
        return new User();
    }

    @GetMapping("/register")
    public String showForm() {
        return "register";
    }
}

The User object is automatically placed into the model, so a view can use it.

You can also explicitly name the attribute:

@ModelAttribute("user")
public User user() {
    return new User();
}

4. @ModelAttribute vs @RequestBody

This is one of the most important distinctions.

@ModelAttribute

@PostMapping("/users")
public String create(@ModelAttribute User user) {
    ...
}

Typically binds form/query parameters:

name=John&age=25

@RequestBody

@PostMapping("/users")
public String create(@RequestBody User user) {
    ...
}

Typically binds a request body, such as JSON:

{
  "name": "John",
  "age": 25
}

So, as a simple rule:

-----------------------------------------------------------------------
Annotation                          Usually used for
----------------------------------- -----------------------------------
`@RequestParam`                     One/small number of request
                                      parameters

`@ModelAttribute`                   Binding multiple form/query
                                      parameters to an object

`@RequestBody`                      Binding JSON/XML request body to an
                                      object

`@PathVariable`                     Values embedded in the URL path
-----------------------------------------------------------------------

A useful mental model

HTML Form
   ↓
name=John
email=john@example.com
age=25
   ↓
@ModelAttribute User
   ↓
User {
    name = "John",
    email = "john@example.com",
    age = 25
}

In short

Use @ModelAttribute when you want Spring MVC to populate a Java object from request parameters, especially for traditional form submissions, or when you want to put an object into the MVC model for a view.

Newer >>