Spring MVC Tutorial
Core Spring MVC
Spring MVC - Annotation
Spring MVC - Form Handling
Spring MVC with JSTL
Spring MVC with REST API
Spring MVC with Database
In traditional web development, two-way data binding is a feature primarily associated with frontend frameworks like Angular, React (with additional libraries), or Vue.js. These frameworks allow automatic synchronization of data between the model (typically JavaScript variables) and the view (UI elements).
However, in the context of Spring MVC, the concept of two-way data binding typically refers to the ability to:
Spring MVC provides this via the @ModelAttribute
annotation.
Let's see a simple example using Spring MVC where a user can edit their profile:
public class UserProfile { private String name; private String email; // Constructors, getters, and setters... }
@Controller @RequestMapping("/profile") public class UserProfileController { // Simulate a user profile from the database UserProfile userProfile = new UserProfile("John Doe", "john.doe@example.com"); @GetMapping("/edit") public String showEditProfile(Model model) { model.addAttribute("userProfile", userProfile); return "editProfile"; } @PostMapping("/save") public String saveProfile(@ModelAttribute UserProfile userProfile) { this.userProfile = userProfile; // Typically, you'd save this to the database return "redirect:/profile/edit"; // Redirect back to the edit page } }
editProfile.jsp
)<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> <html> <head> <title>Edit Profile</title> </head> <body> <form:form action="/profile/save" method="post" modelAttribute="userProfile"> <div> <form:label path="name">Name</form:label> <form:input path="name" /> </div> <div> <form:label path="email">Email</form:label> <form:input path="email" /> </div> <div> <input type="submit" value="Save" /> </div> </form:form> </body> </html>
When a user navigates to /profile/edit
, the showEditProfile
method is invoked. This method populates the model with the current user profile, which is then used to fill the form fields (name
and email
).
After editing the form, the user can submit it. The form data is then automatically collected and bound to the UserProfile
object in the saveProfile
method (thanks to @ModelAttribute
). From here, you can save it to a database, for example.
This example demonstrates two-way data binding in Spring MVC:
Remember to add the necessary dependencies and configuration for Spring MVC to make the above example work.
Using ModelAttribute for two-way data binding in Spring:
@Controller @RequestMapping("/example") public class ExampleController { @GetMapping("/showForm") public String showForm(Model model) { model.addAttribute("user", new User()); return "user-form"; } @PostMapping("/processForm") public String processForm(@ModelAttribute("user") User user) { // The "user" object now contains the form data return "confirmation"; } }
Here, User
is a form backing object with fields corresponding to the form inputs.
Spring MVC form data binding example:
@Controller @RequestMapping("/employee") public class EmployeeController { @GetMapping("/showForm") public String showForm(Model model) { model.addAttribute("employee", new Employee()); return "employee-form"; } @PostMapping("/processForm") public String processForm(@ModelAttribute("employee") Employee employee) { // Process the form data return "confirmation"; } }
The Employee
class is a form backing object with fields corresponding to the form inputs.
Two-way data binding with Thymeleaf in Spring MVC:
<!-- Thymeleaf template: employee-form.html --> <form th:action="@{/employee/processForm}" th:object="${employee}" method="post"> <input type="text" th:field="*{firstName}" /> <input type="text" th:field="*{lastName}" /> <button type="submit">Submit</button> </form>
Thymeleaf's th:field
attribute enables two-way data binding.
Custom converters for two-way data binding in Spring:
public class StringToUserConverter implements Converter<String, User> { @Override public User convert(String source) { // Convert string to User object } }
Register the converter in a configuration class:
@Configuration public class WebConfig implements WebMvcConfigurer { @Override public void addFormatters(FormatterRegistry registry) { registry.addConverter(new StringToUserConverter()); } }
Handling form submissions with two-way data binding in Spring:
@Controller @RequestMapping("/example") public class ExampleController { @PostMapping("/processForm") public String processForm(@ModelAttribute("user") User user) { // Process form data return "confirmation"; } }
Here, User
is the form backing object with fields corresponding to the form inputs.
Spring MVC model attribute and form binding:
@Controller @RequestMapping("/example") public class ExampleController { @ModelAttribute("user") public User getUser() { return new User(); } @GetMapping("/showForm") public String showForm() { return "user-form"; } @PostMapping("/processForm") public String processForm(@ModelAttribute("user") User user) { // Process form data return "confirmation"; } }
The @ModelAttribute
annotated method provides the form backing object to the model.
Binding form data to model in Spring MVC:
@Controller @RequestMapping("/example") public class ExampleController { @GetMapping("/showForm") public String showForm(Model model) { model.addAttribute("user", new User()); return "user-form"; } @PostMapping("/processForm") public String processForm(User user, Model model) { // Process form data model.addAttribute("user", user); return "confirmation"; } }
Here, the User
object is automatically populated with form data.