Kiểm tra ràng buộc dữ liệu
Bộ constraint validation dùng chung cho dữ liệu nghiệp vụ: số điện thoại Việt Nam, toạ độ địa lý, danh sách giá trị cho trước, kèm tiện ích validate thủ công và thông điệp lỗi tiếng Việt/tiếng Anh.
Khi nào sử dụng
- DTO/entity cần ràng buộc số điện thoại theo định dạng Việt Nam thay vì tự viết
@Pattern. - Cần validate chuỗi toạ độ địa lý (
vĩ độ,kinh độ) trước khi lưu. - Cần ràng buộc giá trị nằm trong danh sách cho trước mà không muốn tạo enum cứng.
- Cần validate dữ liệu ngoài luồng request (batch job, import file, trước khi persist) và nhận kết quả dạng map
property -> message. - Muốn thông điệp lỗi validation hiển thị bằng tiếng Việt theo ngôn ngữ của ứng dụng.
Cài đặt
Thêm dependency vào pom.xml, không cần khai báo version vì BOM đã quản lý:
<dependency>
<groupId>vn.govex.cloud</groupId>
<artifactId>govex-cloud-validation</artifactId>
</dependency>
Hướng dẫn khai báo parent/BOM và Maven repository xem tại Cài đặt.
Cấu hình
Các validator được Hibernate Validator phát hiện tự động qua ServiceLoader, nên chỉ cần:
- Có Hibernate Validator trên classpath (ví dụ thông qua
spring-boot-starter-validation) là dùng được ngay, không cần khai báo bean. - Thông điệp lỗi mặc định của Jakarta/Hibernate Validator đã được ghi đè bằng hai file resource đi kèm (tiếng Việt và tiếng Anh); muốn đổi thông điệp riêng thì khai báo
messagengay trên annotation.
Sử dụng
Khai báo ràng buộc trên DTO
Các annotation nằm trong package vn.govex.cloud.api.validation:
import jakarta.validation.constraints.NotBlank;
import vn.govex.cloud.api.validation.EnumValue;
import vn.govex.cloud.api.validation.GeoCoordinate;
import vn.govex.cloud.api.validation.Phone;
public class ContactDTO {
@NotBlank
@Phone
private String phone;
@GeoCoordinate
private String location;
@EnumValue(strValues = {"ACTIVE", "INACTIVE"})
private String status;
}
Ràng buộc được kiểm tra tự động khi controller dùng @Valid:
@PostMapping("/contacts")
public ResultMessage<String> create(@Valid @RequestBody ContactDTO contact) {
return contactService.create(contact);
}
Validate thủ công ngoài luồng request
ValidationResult<ContactDTO> result = ValidationUtils.validateEntity(contact);
if (result.isHasErrors()) {
result.getErrorMsg().forEach((property, message) ->
log.warn("{}: {}", property, message));
}
// Chỉ validate một property cụ thể khi cần
ValidationResult<ContactDTO> phoneResult =
ValidationUtils.validateProperty(contact, "phone");
Ràng buộc tuỳ biến
Cả @Phone và @GeoCoordinate đều cho phép truyền regexp riêng nếu nghiệp vụ cần định dạng khác mặc định; @EnumValue nhận danh sách strValues (chuỗi) hoặc intValues (số nguyên).
Lưu ý
- Annotation thuộc package
vn.govex.cloud.api.validation(tronggovex-cloud-api) — dependencygovex-cloud-validationđã kéo sẵn, không cần khai báo thêm. @Phonechỉ kiểm tra định dạng theo regex mặc định, không xác minh đầu số có thật trên thực tế.- Với giá trị
null/chuỗi rỗng,@Phonevà@GeoCoordinatetrả về hợp lệ — cần kết hợp@NotBlanknếu bắt buộc nhập. @EnumValuechỉ so khớp giá trị theo danh sách truyền vào; giá trịnullkhông bị coi là lỗi, cần thêm@NotNullnếu bắt buộc.ValidationUtilsdùngValidatormặc định của Jakarta Validation (khởi tạo tĩnh), không lấyValidatortuỳ biến từ Spring context; cần customMessageInterpolatorthì dùngValidatorriêng.