Spring Boot Thymeleaf Form Handling Example

In this tutorial, we will learn how to handle forms in Thymeleaf templates in Spring boot applications.

Thymeleaf Form Handling Attributes

Here are the important Thymeleaf attributes that we use while form handling in Thymeleaf templates:
  1. The th:action attribute is used to define the action URL for the form. This attribute replaces the HTML action attribute of a <form>. 
  2. The th:object attribute is used to bind the fields of the form to a model object. 
  3. The th:field attribute points to the field name of the model object.
We will build a User Registration form with different form controls such as input, radio, checkbox, select box, etc.

Create Spring Boot Project

Create a Spring boot project using the spring initializr and add Spring Web and Thymeleaf dependencies:
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-thymeleaf</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

UserForm Model Class

Next, let's create a UserForm model class with the following content into it:
package net.javaguides.thymeleaf.model;

public class UserForm {
    private String name;
    private String email;
    private String password;
    private String gender;
    private String address;
    private boolean married;
    private String profession;

    public String getName() {
        return name;
    }

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

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public boolean isMarried() {
        return married;
    }

    public void setMarried(boolean married) {
        this.married = married;
    }

    public String getProfession() {
        return profession;
    }

    public void setProfession(String profession) {
        this.profession = profession;
    }
}

Spring MVC Controller - FormController

Let's create a FormController and add the handler method to return the Thymeleaf template like:
package net.javaguides.thymeleaf.controller;

import net.javaguides.thymeleaf.model.UserForm;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

import java.util.Arrays;
import java.util.List;

@Controller
public class FormController {

    // handler method to handle user registration page request
    @GetMapping("register")
    public String userRegistrationPage(Model model){
        // Empty UserForm model object to store form data
        UserForm userForm = new UserForm();
        model.addAttribute("userForm", userForm);

        List<String> listProfession = Arrays.asList("Developer", "Tester", "Architect");
        model.addAttribute("listProfession", listProfession);
        return "register-form";
    }
}

Thymeleaf Template - Design User Registration Form

Let's create a Thymeleaf template named register-form.html and design the User Registration form:
<!DOCTYPE html>
<html lang="en"
    xmlns:th="http://www.thymeleaf.org"
>
<head>
    <meta charset="UTF-8">
    <title>User Registration Form</title>
    <style type="text/css">
        label {
            display: inline-block;
            width: 200px;
            margin: 5px;
            text-align: left;
        }
        input[type=text], input[type=email], input[type=password], select {
            display: inline-block;
            width: 200px;
        }
        input[type=radio] {
            margin-left: 45px;
        }
        input[type=checkbox] {
            margin-right: 190px;
        }
        button {
            padding: 5px;
            margin: 10px;
        }
    </style>
</head>
<body>
<div align="center">
    <div style="border-style:solid; width:500px">
        <h1>User Registration</h1>
        <form
            role="form"
            method="post"
            th:action="@{/register/save}"
            th:object="${userForm}"
        >
            <label>Full name:</label>
            <input type="text" th:field = "*{name}" />
            <br />
            <label>E-mail:</label>
            <input type="email" th:field = "*{email}" />
            <br />
            <label>Password:</label>
            <input type="password" th:field="*{password}" />
            <br />
            <label>Gender:</label>
            <input type="radio" th:field="*{gender}" value="Male" /> Male
            <input type="radio" th:field="*{gender}" value="Female" /> Female
            <br />
            <label>Profession:</label>
            <select th:field="*{profession}">
                <option th:each="p : ${listProfession}" th:value="${p}" th:text="${p}"></option>
            </select>
            <br />
            <label>Address:</label>
            <textarea rows="5" cols="25" th:field="*{address}">
            </textarea>
            <br />
            <button type="submit">Register</button>
        </form>
    </div>
</div>
</body>
</html>
The th:action attribute is used to define the action URL for the form. This attribute replaces the HTML action attribute of a <form>. 

The th:object attribute is used to bind the fields of the form to a model object. 

The th:field attribute points to the field name of the model object.

Thymeleaf Template - Display User Registration Form Data

Let's first add a handler method (submitForm) to handle user registration form submission request:
    // handler method to handle user registration form submission request
    @PostMapping("register/save")
    public String submitForm(Model model,
                             @ModelAttribute("userForm") UserForm userForm){
        model.addAttribute("userForm", userForm);
        return "register-success";
    }
Complete FormController code:
package net.javaguides.thymeleaf.controller;

import net.javaguides.thymeleaf.model.UserForm;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;

import java.util.Arrays;
import java.util.List;

@Controller
public class FormController {

    // handler method to handle user registration page request
    @GetMapping("register")
    public String userRegistrationPage(Model model){
        // Empty UserForm model object to store form data
        UserForm userForm = new UserForm();
        model.addAttribute("userForm", userForm);

        List<String> listProfession = Arrays.asList("Developer", "Tester", "Architect");
        model.addAttribute("listProfession", listProfession);
        return "register-form";
    }

    // handler method to handle user registration form submission request
    @PostMapping("register/save")
    public String submitForm(Model model,
                             @ModelAttribute("userForm") UserForm userForm){
        model.addAttribute("userForm", userForm);
        return "register-success";
    }
}
Now, let's create a Thymeleaf template named register-success to display registered form data:
<!DOCTYPE html>
<html lang="en"
    xmlns:th="http://www.thymeleaf.org"
>
<head>
    <meta charset="UTF-8">
    <title>User Registered Data</title>
</head>
<body>
<div align="center">
    <h1>Registered User Information</h1>
    <div>
        <p>Name: <strong th:text="${userForm.name}"></strong></p>
        <p>Email: <strong th:text="${userForm.email}"></strong></p>
        <p>Password: <strong th:text="${userForm.password}"></strong></p>
        <p>Gender: <strong th:text="${userForm.gender}"></strong></p>
        <p>Address: <strong th:text="${userForm.address}"></strong></p>
        <p>Married: <strong th:text="${userForm.married}"></strong></p>
        <p>Profession: <strong th:text="${userForm.profession}"></strong></p>
    </div>
</div>
</body>
</html>

Demo

Run the Spring boot application and hit the below link in the browser:

Here is the output:

Display registered form data:

Comments