1. Giới thiệu
Bản thân Hibenate và Java đã cung cấp cho chúng ta rất nhiều phương thức để validate model như: @Size, @NotNull, @NotEmpty, @NotBlank, @Email, @Min, @Max, …
Tuy nhiên trên project thực tế có rất nhiều yêu cầu đặt ra, tuỳ thuộc vào business và quy mo project.
Ví dụ như một đối tượng Book có thuộc tính là code để quản lý mã của sách đó trong hệ thống của nhà sách. Một book code hợp lệ phài bắt đầu bằng “BK_”.
2. Setup
Thêm dependency vào pom.xml
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.10.Final</version>
</dependency>
3. Create Model & Controller
package com.example.demo.LearnController;
public class BookRequest {
private String title;
private String code;
private String author;
}
@RestController
public class BookController {
@PostMapping("/book")
public String postRequest(@Valid @RequestBody BookRequest bookRequest) {
return bookRequest.toString();
}
}
4. Create Annotation
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;
@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = BookCodeValidator.class)
public @interface BookCodeVerify {
String message() default "Invalid book code.";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
5. Create Validator
import javax.validation.ConstraintValidatorContext;
public class ConstraintValidatorUtils {
private ConstraintValidatorUtils() { }
public static void createConstraintViolation(ConstraintValidatorContext context, String errorCode) {
// Disable nhung tham so constraint violation mac dinh
context.disableDefaultConstraintViolation();
// Them nhung tham so constraint violation duoc truyen vao thong qua method nay
addConstraintViolation(context, errorCode);
}
public static void addConstraintViolation(ConstraintValidatorContext context, String errorCode) {
ConstraintValidatorContext.ConstraintViolationBuilder builder = context.buildConstraintViolationWithTemplate(errorCode);
builder.addConstraintViolation();
}
}
import org.springframework.util.StringUtils;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
public class BookCodeValidator implements ConstraintValidator<BookCodeVerify, String> {
private static final String BOOK_CODE_PREFIX = "BK_";
@Override
public boolean isValid(String code, ConstraintValidatorContext context) {
if(!StringUtils.hasText(code)) {
ConstraintValidatorUtils.createConstraintViolation(context, "Please enter book code.");
return false;
}
if (!code.startsWith(BOOK_CODE_PREFIX)) {
ConstraintValidatorUtils.createConstraintViolation(context,"Book code must be start with BK_");
return false;
}
return true;
}
}
6. Applying Validation Annotation
Gắn @BookCodeVerify vào thuộc tính muốn validate
import com.example.demo.Validator.BookCodeVerify;
public class BookRequest {
private String title;
@BookCodeVerify
private String code;
private String author;
}
7. Test with API
7.1 Attribute valid

7.2 Attribute blank

{
"timestamp": "2021-06-01T11:06:33.225+00:00",
"status": 400,
"error": "Bad Request",
"errors": [
{
"codes": [
"BookCodeVerify.bookRequest.code",
"BookCodeVerify.code",
"BookCodeVerify.java.lang.String",
"BookCodeVerify"
],
"arguments": [
{
"codes": [
"bookRequest.code",
"code"
],
"arguments": null,
"defaultMessage": "code",
"code": "code"
}
],
"defaultMessage": "Please enter book code.",
"objectName": "bookRequest",
"field": "code",
"rejectedValue": "",
"bindingFailure": false,
"code": "BookCodeVerify"
}
],
"path": "/book"
}
7.3 Attribute invalid

{
"timestamp": "2021-06-01T11:02:18.152+00:00",
"status": 400,
"error": "Bad Request",
"errors": [
{
"codes": [
"BookCodeVerify.bookRequest.code",
"BookCodeVerify.code",
"BookCodeVerify.java.lang.String",
"BookCodeVerify"
],
"arguments": [
{
"codes": [
"bookRequest.code",
"code"
],
"arguments": null,
"defaultMessage": "code",
"code": "code"
}
],
"defaultMessage": "Book code must be start with BK_",
"objectName": "bookRequest",
"field": "code",
"rejectedValue": "cleancode",
"bindingFailure": false,
"code": "BookCodeVerify"
}
],
"path": "/book"
}
Be First to Comment