Swiftorial Logo
Home
Swift Lessons
Matchups
CodeSnaps
Tutorials
Career
Resources

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[] 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 and BindingResult 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!