Spring MVC – Phần 7: Form validation, Code ví dụ validate form trong Spring MVC
Spring hỗ trợ validate các field/thuộc tính khi submit form bằng cách sử dụng các annotation validate của hibernate-validator, javax-validation.
Trong bài này mình sẽ hướng dẫn thực hiện một ví dụ validate 1 form submit với các thuộc tính có nhiều kiểu dữ liệu khác nhau, cách tạo 1 annotation validate.
Form validation, Code ví dụ validate form trong Spring MVC
1. Cấu trúc Project ví dụ:
2. Code ví dụ
Thư viện sử dụng:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>stackjava.com</groupId> <artifactId>SpringFormValidation</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>war</packaging> <properties> <spring.version>5.0.2.RELEASE</spring.version> </properties> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>javax.validation</groupId> <artifactId>validation-api</artifactId> <version>1.1.0.Final</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>5.4.2.Final</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> </dependencies> </project>
Hai thư viện validation-api và hibernate-validator cung cấp các annotation định nghĩa cho việc validate
File Spring Config
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd"> <!-- Enables the Spring MVC @Controller programming model --> <mvc:annotation-driven /> <context:component-scan base-package="stackjava.com.springmvchello" /> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix"> <value>/WEB-INF/views/jsp/</value> </property> <property name="suffix"> <value>.jsp</value> </property> </bean> <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource"> <property name="basename" value="/i18n/message" /> </bean> </beans>
(*Lưu ý: bắt buộc dùng <mvc:annotation-driven /> để xử lý các annotation @Valid, @Validate cho controller)
File entity:
public class User { @NotNull(message = "Id may not be null") private Integer id; @NotBlank @Length(min = 5, max = 10) private String name; @NotBlank @Email private String email; @NotNull @DateTimeFormat(pattern = "dd/MM/yyyy") @Past private Date dateOfBirth; @Phone(message = "Phone Number is invalid") private String phoneNumber; // getter/setter }
Các annotation khai báo trước các field sẽ định nghĩa ràng buộc cho các field đó.
Mặc định các message lỗi sẽ được lấy từ file .properties, nếu không tìm thấy thì nó sẽ thấy theo các message khai báo bên cạnh annotation, nếu không tìm thấy cả 2 chỗ trên thì nó sẽ thấy message mặc định của hibernate-validator và validation-api.
Ví dụ:
- field name không được để trống và chiều dài từ 5-10 ký tự
- field dateOfBirth: không được null, có định dạng là dd/MM/yyyy và phải trước ngày hiện tại
Một số annotation validate khác hay dùng như @Size, @Future, @Pattern… Annotation @Phone là do mình tự định nghĩa:
Ở đây mình định nghĩa số điện thoại có định dạng là số và chiều dài là 10 ký tự.
@Documented @Constraint(validatedBy = PhoneValidator.class) @Retention(RUNTIME) @Target({ FIELD, METHOD }) public @interface Phone { String message() default "{Phone}"; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; }
public class PhoneValidator implements ConstraintValidator<Phone, String> { public void initialize(Phone paramA) { } public boolean isValid(String phoneNo, ConstraintValidatorContext ctx) { if (phoneNo == null) { return false; } return phoneNo.matches("\\d{10}"); } }
Controller:
@Controller public class UserController { @RequestMapping(value = "/addUser", method = RequestMethod.GET) public String doGetAddUser(Model model) { if (!model.containsAttribute("user")) { model.addAttribute("user", new User()); } return "add-user"; } @RequestMapping(value = "/addUser", method = RequestMethod.POST) public String doPostAddUser(@ModelAttribute("user") @Valid User user, BindingResult result) { if (result.hasErrors()) { return "add-user"; } return "view-user"; } }
*Lưu ý: Trong method của controller, BindingResult phải nằm ngay sau đối tượng được validate.
Bạn có thể dùng annotation @Valid (javax.validation.valid) hoặc @Validate (org.springframework.validation.annotation.validate) đều được.
File jsp hiển thị:
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%> <html> <head> <style> .error { color: red; } </style> </head> <body> <h2>add-user.jsp</h2> <form:form action="addUser" method="POST" modelAttribute="user"> Id: <form:input path="id"/> <form:errors path="id" cssClass="error"/> <br/><br/> Name: <form:input path="name"/> <form:errors path="name" cssClass="error"/> <br/><br/> Email: <form:input path="email"/> <form:errors path="email" cssClass="error"/> <br/><br/> Phone Number: <form:input path="phoneNumber"/> <form:errors path="phoneNumber" cssClass="error"/> <br/><br/> Date Of Birth: <form:input path="dateOfBirth"/> <form:errors path="dateOfBirth" cssClass="error"/> <br/> <button type="submit">Submit</button> </form:form> </body> </html>
<%@ taglib prefix = "fmt" uri = "http://java.sun.com/jsp/jstl/fmt" %> <html> <head> <title>Spring MVC Form Validation</title> </head> <body> <h2>add-user.jsp</h2> Id: ${user.id} <br/> Name: ${user.name}<br/> Email: ${user.email }<br/> Phone Number: ${user.phoneNumber }<br/> Date Of Birth: <fmt:formatDate pattern = "dd/MM/yyyy" value = "${user.dateOfBirth}"/> </body> </html>
File message:
## Chỉ rõ message lỗi cho đối tượng NotNull.user.id=Id can not be null NotBlank.user.name=Name can not be empty NotBlank.user.email=Email can not be null NotNull.user.dateOfBirth=Date of birth can not be null Past.user.dateOfBirth=Must be in the past Email.user.email=Email is wrong format ## Message lỗi chung cho Annotation ##NotNull=Not null ##NotBlank=Not Blank ##Email=Email is wrong format ##Past=Must be in the Past # Message lỗi cho customer annotation Phone=Phone number is not valid
Form validation, Code ví dụ validate form trong Spring MVC
Demo:
Trường hợp các giá trị nhập vào sai định dạng/ để trống
Trường hợp các field nhập vào hợp lệ
Okay Done!
Download code ví dụ trên tại đây
References:
https://spring.io/guides/gs/validating-form-input/
https://docs.spring.io/spring/docs/4.1.x/spring-framework-reference/html/validation.html