Form Handling in Thymeleaf
Forms are how users send data to your server. Thymeleaf makes it easy to bind form fields to Java objects and handle submissions. Let's see how.
Basic Form with th:action
The th:action attribute sets the form's URL. Use @{...} syntax so Thymeleaf handles the context path for you.
<form th:action="@{/submit}" method="post">
<label for="name">Name:</label>
<input type="text" id="name" name="name"/>
<button type="submit">Submit</button>
</form>
The @{/submit} ensures the URL works no matter where your app is deployed. If your app is at /myapp, it generates /myapp/submit.
Binding to an Object with th:object
Instead of reading individual parameters, you can bind the whole form to a Java object. Use th:object with th:field to connect fields.
<form th:action="@{/submit}" th:object="${user}" method="post">
<label for="name">Name:</label>
<input type="text" id="name" th:field="*{name}"/>
<label for="email">Email:</label>
<input type="email" id="email" th:field="*{email}"/>
<button type="submit">Submit</button>
</form>
When you submit this form, Spring automatically populates the User object. th:field="*{name}" binds to user.getName() and sets the input's name, id, and value attributes.
Hidden Fields
Sometimes you need to pass data without showing it to the user. Use a hidden input with th:field to include values the user can't edit.
<form th:action="@{/submit}" th:object="${user}" method="post">
<input type="hidden" th:field="*{id}"/>
<label for="name">Name:</label>
<input type="text" id="name" th:field="*{name}"/>
<button type="submit">Update</button>
</form>
The id field is sent with the form but never displayed. This is useful for update operations where you need to know which record to modify.
The Controller Side
Your controller needs to provide the empty object for the form and handle the submitted data.
@Controller
public class UserController {
@GetMapping("/form")
public String showForm(Model model) {
model.addAttribute("user", new User());
return "form";
}
@PostMapping("/submit")
public String handleSubmit(@ModelAttribute User user) {
System.out.println("Name: " + user.getName());
return "result";
}
}
The @ModelAttribute tells Spring to bind the form data to the User object. The model attribute name "user" matches what we used in the template.