Open In App

Spring – MVC Regular Expression Validation

Last Updated : 21 Mar, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Regular Expression Validation in Spring MVC can be achieved by using Hibernate Validator which is the implementation of Bean Validation API. Hibernate Validator provides @Pattern annotation which is used for regular expression validation.

Syntax:

@Pattern(regex="", flag="", message="")
private String someDataMember;

Note that the flag and message attributes are optional. Let’s build a simple web application for a better understanding of how to use Regex validation in Spring MVC. In this application, we will build a guest login page.

Example

Project structure: 

Project structure

Project structure for guest login application

Regex Usage: 

The @Pattern annotation makes sure that the value passed to the data member follows the provided regular expressions. The attribute regexp takes the regular expression to be matched.

@Pattern(regexp = "^[a-zA-Z0-9]{6,12}$",
            message = "username must be of 6 to 12 length with no special characters")
private String username;

In the above code snippet, the regular expression says that a username can contain any lowercase characters, any uppercase characters, or any digit only. Also, the username can only be of 6 to 12 lengths (inclusive).

@Pattern(regexp = "^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#$%^&*])[a-zA-Z0-9!@#$%^&*]{4,12}$",
            message = "password must be min 4 and max 12 length containing atleast 1 uppercase, 1 lowercase, 1 special character and 1 digit ")
private String password;

In the above code snippet, the regular expression says that the password must contain at least 1 lowercase letter, 1 uppercase letter, 1 special character, and 1 digit and it must be of size 4 to 12 inclusive. 

User class (Data model): 

Java




import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.constraints.*;
 
@Data
@AllArgsConstructor
@NoArgsConstructor
class User {
 
    @Pattern(regexp = "^[a-zA-Z0-9]{6,12}$",
            message = "username must be of 6 to 12 length with no special characters")
    private String username;
 
    @Pattern(regexp = "^((?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$&*])(?=.*[0-9])){4,12}$",
            message = "password must contain atleast 1 uppercase, 1 lowercase, 1 special character and 1 digit ")
    private String password;
}


The User class acts as a data model for our application. Here we have used Lombok to reduce boilerplate code. The User class consists of only 2 fields required for our guest login page.

APIs: Our application consists of the following APIs.

@GetMapping("/")
  public String getForm(User user) {
      return "login";
}

The above code snippet demonstrates the GET API which is used here to render the login.html page residing in our resources/templates files. The endpoint for the GET API is “/”.

@PostMapping("/")
 public String login(@Valid User user, Errors errors, Model model) {
     if (errors.hasErrors()) {
        return "login";
    } else {
        model.addAttribute("message", "Guest login successful ...");
        return "login";
    }
}

The above code snippet demonstrates the POST API which is used to take login form input and passes the errors (if any) of the regex validation to the login page which then renders it.

Complete Controller Class: 

Java




import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
 
import javax.validation.Valid;
 
@Controller
public class LoginController {
 
    @GetMapping("/")
    public String getForm(User user) {
        return "login";
    }
 
    @PostMapping("/")
    public String login(@Valid User user, Errors errors, Model model) {
        if (errors.hasErrors()) {
            return "login";
        } else {
            model.addAttribute("message", "Guest login successful ...");
            return "login";
        }
    }
}


Note : 

  • The @Controller annotation indicates that a particular class serves the role of a controller.
  • @GetMapping is used to handle GET type of request method.
  • @PostMapping is used to handle POST type of request method.

Login page (Html + Thymleaf): 

HTML




<!DOCTYPE html>
<html lang="en" xmlns:th="http://thymeleaf.org">
<head>
    <title>Guest Login</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
    <h1 th:text="${message}" style="text-align: center; padding-top: 40px"></h1>
 
    <div class="container" style="padding-top: 50px ">
        <h2>Guest login</h2>
        <form action="/" th:action="@{/}" th:object="${person}" method="post" style="padding-top: 30px">
            <div class="form-group">
                <label for="username">Username:</label>
                <input type="text" class="form-control" id="username" placeholder="Enter username" name="username" th:field="*{username}"> <br />
                <p th:if="${#fields.hasErrors('username')}" th:errors="*{username}" class="alert alert-danger"></p>
 
            </div>
     
            <div class="form-group">
                <label for="password">Password:</label>
                <input type="text" class="form-control" id="password" placeholder="Enter password" name="password" th:field="*{password}"> <br />
                <p th:if="${#fields.hasErrors('password')}" th:errors="*{password}" class="alert alert-danger"></p>
 
            </div>
     
            <div class="form-group form-check">
                <label class="form-check-label"> <input class="form-check-input" type="checkbox" name="remember">
                    Remember me
                </label>
            </div>
            <button type="submit" class="btn btn-primary">Submit</button>
        </form>
    </div>
 
</body>
</html>


The above code represents our login page. Here we have used thymleaf instead of JSP which is a templating engine that is certainly a better way of creating templates.

Dependency:

Add the below dependencies in the pom.xml file.

XML




<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>
<dependency>
    <groupId>org.hibernate.validator</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>6.2.0.Final</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
    <scope>runtime</scope>
    <optional>true</optional>
</dependency>
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>


Output:

Output

Let’s try to validate it with some invalid input data. Example:

  • Username: anu0-0
  • Password: QWqw123

Since the username doesn’t allow special characters and the password requires a special character, error messages will be passed to the login page and then rendered showing that the input data doesn’t match the given regex format.

Output

Invalid input data

Let’s try to validate it with some valid input data. Example: 

  • Username: anu000
  • Password: QWqw@123

Output



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads