La validación de expresiones regulares en Spring MVC se puede lograr utilizando Hibernate Validator, que es la implementación de Bean Validation API. Hibernate Validator proporciona la anotación @Pattern que se utiliza para la validación de expresiones regulares.
Sintaxis:
@Pattern(regex="", flag="", message="") private String someDataMember;
Tenga en cuenta que los atributos de bandera y mensaje son opcionales. Construyamos una aplicación web simple para una mejor comprensión de cómo usar la validación Regex en Spring MVC. En esta aplicación, crearemos una página de inicio de sesión para invitados.
Ejemplo
Estructura del proyecto:
Uso de expresiones regulares:
La anotación @Pattern se asegura de que el valor pasado al miembro de datos siga las expresiones regulares proporcionadas. El atributo regexp toma la expresión regular para que coincida.
@Pattern(regexp = "^[a-zA-Z0-9]{6,12}$", message = "username must be of 6 to 12 length with no special characters") private String username;
En el fragmento de código anterior, la expresión regular dice que un nombre de usuario puede contener cualquier carácter en minúscula, cualquier carácter en mayúscula o cualquier dígito solamente. Además, el nombre de usuario solo puede tener de 6 a 12 longitudes (inclusive).
@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;
En el fragmento de código anterior, la expresión regular dice que la contraseña debe contener al menos 1 letra minúscula, 1 letra mayúscula, 1 carácter especial y 1 dígito y debe tener un tamaño de 4 a 12 inclusive.
Clase de usuario (modelo de datos):
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; }
La clase User actúa como un modelo de datos para nuestra aplicación. Aquí hemos usado Lombok para reducir el código repetitivo. La clase de usuario consta de solo 2 campos necesarios para nuestra página de inicio de sesión de invitados.
APIs: Nuestra aplicación consta de las siguientes APIs.
@GetMapping("/") public String getForm(User user) { return "login"; }
El fragmento de código anterior demuestra la API GET que se utiliza aquí para representar la página login.html que reside en nuestros archivos de recursos/plantillas. El punto final de la API GET es «/».
@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"; } }
El fragmento de código anterior demuestra la API POST que se usa para tomar la entrada del formulario de inicio de sesión y pasa los errores (si los hay) de la validación de expresiones regulares a la página de inicio de sesión que luego los representa.
Clase de controlador completa:
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"; } } }
Nota :
- La anotación @Controller indica que una clase en particular cumple la función de un controlador.
- @GetMapping se usa para manejar el tipo de método de solicitud GET.
- @PostMapping se usa para manejar el tipo POST de método de solicitud.
Página de inicio de sesión (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"> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.0/umd/popper.min.js"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js"></script> </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>
El código anterior representa nuestra página de inicio de sesión. Aquí hemos usado thymleaf en lugar de JSP, que es un motor de plantillas que sin duda es una mejor manera de crear plantillas.
Dependencia:
Agregue las siguientes dependencias en el archivo pom.xml.
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>
Producción:
Intentemos validarlo con algunos datos de entrada no válidos. Ejemplo:
- Nombre de usuario : anu0-0
- Contraseña : QWqw123
Dado que el nombre de usuario no permite caracteres especiales y la contraseña requiere un carácter especial, los mensajes de error se pasarán a la página de inicio de sesión y luego se mostrarán mostrando que los datos de entrada no coinciden con el formato de expresión regular dado.
Intentemos validarlo con algunos datos de entrada válidos. Ejemplo:
- Nombre de usuario : anu000
- Contraseña : QWqw@123