Form Validation in Spring MVC
Form validation in Spring MVC involves ensuring that the data entered into forms meets specific criteria before it is processed. This guide covers the key concepts and steps for implementing form validation in Spring MVC, including using JSR-303/JSR-380 annotations, handling validation errors, and displaying error messages in views.
Key Concepts of Form Validation
- JSR-303/JSR-380 Annotations: Standard Java annotations for bean validation.
- @Valid: Indicates that a method parameter should be validated.
- BindingResult: Holds the results of a validation and binding and contains errors that may have occurred.
Adding Validation Annotations
Use JSR-303/JSR-380 annotations to define validation rules in your form backing object:
User.java
// User.java
package com.example.springmvc.models;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotEmpty;
public class User {
@NotEmpty(message = "Name is required")
private String name;
@NotEmpty(message = "Email is required")
@Email(message = "Email should be valid")
private String email;
// Getters and Setters
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;
}
}
Creating the Form
Create an HTML form that binds to the form backing object and displays validation errors:
userForm.jsp
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %>
<html>
<head>
<title>User Form</title>
</head>
<body>
<h2>User Form</h2>
<form:form method="post" action="submitUserForm" modelAttribute="user">
<form:errors path="*" cssClass="error-message" />
<form:label path="name">Name:</form:label>
<form:input path="name" />
<form:errors path="name" cssClass="error-message" />
<br/>
<form:label path="email">Email:</form:label>
<form:input path="email" />
<form:errors path="email" cssClass="error-message" />
<br/>
<input type="submit" value="Submit" />
</form:form>
</body>
</html>
Handling Validation in the Controller
Use the @Valid
annotation and BindingResult
to handle validation in the controller:
UserController.java
// UserController.java
package com.example.springmvc.controllers;
import com.example.springmvc.models.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import javax.validation.Valid;
@Controller
public class UserController {
@GetMapping("/userForm")
public String showUserForm(Model model) {
model.addAttribute("user", new User());
return "userForm";
}
@PostMapping("/submitUserForm")
public String submitUserForm(@Valid @ModelAttribute User user, BindingResult result, Model model) {
if (result.hasErrors()) {
return "userForm";
}
model.addAttribute("user", user);
return "userDetails";
}
}
Displaying Validation Errors
Use the form:errors
tag to display validation errors in the view:
userForm.jsp
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %>
<html>
<head>
<title>User Form</title>
</head>
<body>
<h2>User Form</h2>
<form:form method="post" action="submitUserForm" modelAttribute="user">
<form:errors path="*" cssClass="error-message" />
<form:label path="name">Name:</form:label>
<form:input path="name" />
<form:errors path="name" cssClass="error-message" />
<br/>
<form:label path="email">Email:</form:label>
<form:input path="email" />
<form:errors path="email" cssClass="error-message" />
<br/>
<input type="submit" value="Submit" />
</form:form>
</body>
</html>
Custom Validation
You can create custom validation annotations and validators to handle more complex validation logic. Here is an example of a custom validator:
ValidPassword.java
// ValidPassword.java
package com.example.springmvc.validation;
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Constraint(validatedBy = PasswordValidator.class)
@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ValidPassword {
String message() default "Invalid password";
Class>[] groups() default {};
Class extends Payload>[] payload() default {};
}
PasswordValidator.java
// PasswordValidator.java
package com.example.springmvc.validation;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
public class PasswordValidator implements ConstraintValidator {
@Override
public void initialize(ValidPassword constraintAnnotation) {
}
@Override
public boolean isValid(String password, ConstraintValidatorContext context) {
return password != null && password.length() >= 8 && password.matches(".*\\d.*");
}
}
User.java (with Custom Validation)
// User.java
package com.example.springmvc.models;
import com.example.springmvc.validation.ValidPassword;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotEmpty;
public class User {
@NotEmpty(message = "Name is required")
private String name;
@NotEmpty(message = "Email is required")
@Email(message = "Email should be valid")
private String email;
@NotEmpty(message = "Password is required")
@ValidPassword
private String password;
// Getters and Setters
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;
}
}
Key Points
- JSR-303/JSR-380 Annotations: Standard Java annotations for bean validation.
- @Valid: Indicates that a method parameter should be validated.
- BindingResult: Holds the results of a validation and binding and contains errors that may have occurred.
- Use JSR-303/JSR-380 annotations to define validation rules in your form backing object.
- Use the
@Valid
annotation andBindingResult
to handle validation in the controller. - Use the
form:errors
tag to display validation errors in the view. - Create custom validation annotations and validators for more complex validation logic.
Conclusion
Form validation in Spring MVC ensures that the data entered into forms meets specific criteria before it is processed. By using JSR-303/JSR-380 annotations, handling validation errors with BindingResult
, and displaying error messages in views, developers can create robust and user-friendly forms in their Spring MVC applications. Happy coding!