0Pricing
Java Academy · บทเรียน

คำอธิบายข้อจำกัดแบบกำหนดเอง

สร้างคำอธิบาย @UniqueEmail แบบกำหนดเองพร้อมการใช้งาน ConstraintValidator

คำอธิบายข้อจำกัดแบบกำหนดเอง เป็นบทเรียน Java Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Java Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Java Academy มีบทเรียนทั้งหมด 4 บทเรียน

เมื่อข้อจำกัดมาตรฐานไม่เพียงพอ

คำอธิบายประกอบการตรวจสอบความถูกต้องของบีนมาตรฐานครอบคลุมกรณีทั่วไป หากต้องใช้กฎเฉพาะโดเมน (เช่น อีเมลไม่ซ้ำ IBAN ที่ถูกต้อง หรือความแข็งแกร่งของรหัสผ่าน) ให้สร้างคำอธิบายประกอบข้อจำกัดแบบกำหนดเอง

การกำหนดคำอธิบายประกอบข้อจำกัด

สร้างคำอธิบายประกอบด้วย @Constraint(validatedBy = ...) พร้อมองค์ประกอบ message, groups และ payload ที่จำเป็น รวมถึงกำหนดการคงอยู่และเป้าหมายที่เหมาะสม

import jakarta.validation.Constraint;
import jakarta.validation.Payload;
@Documented
@Constraint(validatedBy = UniqueEmailValidator.class)
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface UniqueEmail {
    String message() default "Email already registered";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

การใช้งาน ConstraintValidator

ใช้งาน ConstraintValidator<UniqueEmail, String> เมธอด initialize จะอ่านองค์ประกอบของคำอธิบายประกอบ ส่วน isValid จะดำเนินการตรวจสอบจริง

@Component
public class UniqueEmailValidator implements ConstraintValidator<UniqueEmail, String> {
    @Autowired private UserRepository repo;
    @Override
    public boolean isValid(String email, ConstraintValidatorContext ctx) {
        if (email == null) return true; // let @NotBlank handle null
        return !repo.existsByEmail(email);
    }
}

การใช้ข้อจำกัดแบบกำหนดเอง

ใช้คำอธิบายประกอบนี้เช่นเดียวกับข้อจำกัดมาตรฐานกับฟิลด์ พารามิเตอร์ หรือค่าที่ส่งคืน

public record CreateUserRequest(
    @NotBlank
    String name,
    @NotBlank @Email @UniqueEmail
    String email
) {}

ข้อความแบบกำหนดเองพร้อมการแทนค่า

อ้างอิงองค์ประกอบของคำอธิบายประกอบในข้อความด้วย {elementName} ใช้ ctx.buildConstraintViolationWithTemplate() เพื่อเพิ่มข้อความแบบกำหนดเองที่มีข้อมูลแบบไดนามิก

@Constraint(validatedBy = RangeValidator.class)
public @interface InRange {
    int min() default 0;
    int max() default 100;
    String message() default "Must be between {min} and {max}";
    // ...
}

ข้อจำกัดระดับคลาส

ใช้ข้อจำกัดในระดับคลาสเพื่อตรวจสอบหลายฟิลด์ร่วมกัน เหมาะสำหรับกฎข้ามฟิลด์ เช่น การยืนยันรหัสผ่าน

@Documented
@Constraint(validatedBy = PasswordMatchValidator.class)
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface PasswordMatch {
    String message() default "Passwords do not match";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

การใช้งานตัวตรวจสอบระดับคลาส

ตัวตรวจสอบจะได้รับออบเจ็กต์ทั้งหมด จึงสามารถเข้าถึงหลายฟิลด์เพื่อทำการตรวจสอบข้ามฟิลด์

public class PasswordMatchValidator implements ConstraintValidator<PasswordMatch, ChangePasswordRequest> {
    public boolean isValid(ChangePasswordRequest req, ConstraintValidatorContext ctx) {
        if (req.getNewPassword() == null) return true;
        boolean match = req.getNewPassword().equals(req.getConfirmPassword());
        if (!match) {
            ctx.disableDefaultConstraintViolation();
            ctx.buildConstraintViolationWithTemplate("Passwords do not match")
               .addPropertyNode("confirmPassword").addConstraintViolation();
        }
        return match;
    }
}

การประกอบข้อจำกัด

สร้างข้อจำกัดเมตาโดยใส่คำอธิบายประกอบข้อจำกัดแบบกำหนดเองด้วยข้อจำกัดที่มีอยู่แล้ว ระบบจะใช้ข้อจำกัดทั้งสองรายการโดยอัตโนมัติ

@NotBlank
@Email
@Size(max = 255)
@Constraint(validatedBy = {})
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ValidEmail {
    String message() default "Invalid email";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

การส่งคืนการละเมิดหลายรายการ

ใช้ ctx.disableDefaultConstraintViolation() และเพิ่มข้อความการละเมิดแยกกันสำหรับแต่ละปัญหาที่พบในการตรวจสอบหนึ่งรอบ

public boolean isValid(String password, ConstraintValidatorContext ctx) {
    List<String> issues = new ArrayList<>();
    if (password.length() < 8) issues.add("Too short");
    if (!password.matches(".*\\d.*")) issues.add("Must contain a digit");
    if (issues.isEmpty()) return true;
    ctx.disableDefaultConstraintViolation();
    issues.forEach(msg -> ctx.buildConstraintViolationWithTemplate(msg).addConstraintViolation());
    return false;
}

ตัวตรวจสอบที่จัดการโดยสปริง

เนื่องจาก UniqueEmailValidator มีคำอธิบายประกอบ @Component สปริงจึงฉีดรีโพซิทอรีเข้าไปได้ แต่จะทำงานได้ก็ต่อเมื่อตัวตรวจสอบเริ่มต้นผ่านตัวตรวจสอบของสปริง ซึ่ง Spring Boot จะเชื่อมต่อให้โดยอัตโนมัติ

การทดสอบตัวตรวจสอบแบบกำหนดเอง

ทดสอบตัวตรวจสอบแบบยูนิตโดยตรงได้ โดยไม่ต้องใช้บริบทของสปริงสำหรับตรรกะการตรวจสอบที่ไม่มีการพึ่งพาภายนอก ใช้ Validation.buildDefaultValidatorFactory() สำหรับการทดสอบการผสานรวม

Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
CreateUserRequest req = new CreateUserRequest("", "bad-email", null);
Set<ConstraintViolation<CreateUserRequest>> violations = validator.validate(req);
System.out.println(violations.size()); // 3

ตรวจสอบความเข้าใจอย่างรวดเร็ว

ตัวตรวจสอบข้อจำกัดแบบกำหนดเองใช้อินเทอร์เฟซใด

สรุปทบทวน

สร้าง @interface ด้วย @Constraint(validatedBy=...) และใช้งาน ConstraintValidator ใช้ @Component สำหรับการฉีดการพึ่งพาของสปริง ข้อจำกัดระดับคลาสใช้ตรวจสอบหลายฟิลด์ร่วมกัน และสามารถประกอบข้อจำกัดที่มีอยู่แล้วเพื่อหลีกเลี่ยงการทำซ้ำ

คำถามที่พบบ่อย

บทเรียน “คำอธิบายข้อจำกัดแบบกำหนดเอง” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “คำอธิบายข้อจำกัดแบบกำหนดเอง” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Java Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Java Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “คำอธิบายข้อจำกัดแบบกำหนดเอง”

สร้างคำอธิบาย @UniqueEmail แบบกำหนดเองพร้อมการใช้งาน ConstraintValidator คุณปฏิบัติ Java Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Java Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Java Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน

บทเรียน “คำอธิบายข้อจำกัดแบบกำหนดเอง” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Java Academy นี้ได้ไหม

ได้ บทเรียน Java Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. การตรวจสอบ Bean: @NotNull, @Size, @Pattern
  2. คำอธิบายข้อจำกัดแบบกำหนดเอง
  3. การจัดการข้อยกเว้นแบบรวมศูนย์ด้วย @ControllerAdvice
  4. รายละเอียดปัญหา RFC 7807 และการตอบกลับข้อผิดพลาดอย่างสอดคล้อง
← กลับไปที่ Java Academy