0Pricing
Java Academy · Pelajaran

Anotasi Batasan Khusus

Buat anotasi @UniqueEmail khusus dengan implementasi ConstraintValidator.

Anotasi Batasan Khusus adalah pelajaran Java Academy gratis di CoddyKit. Ini adalah pelajaran 2 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar Java Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus Java Academy mencakup 4 pelajaran total.

Saat Batasan Standar Belum Memadai

Anotasi Validasi Bean standar mencakup kasus umum. Untuk aturan khusus domain (misalnya, email unik, IBAN valid, dan kekuatan kata sandi), buat anotasi batasan kustom.

Mendefinisikan Anotasi Batasan

Buat anotasi dengan @Constraint(validatedBy = ...), elemen message, groups, dan payload yang diperlukan, serta retensi/sasaran yang sesuai.

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 {};
}

Mengimplementasikan ConstraintValidator

Implementasikan ConstraintValidator<UniqueEmail, String>. Metode initialize membaca elemen anotasi; isValid melakukan pemeriksaan sebenarnya.

@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);
    }
}

Menggunakan Batasan Kustom

Terapkan anotasi seperti batasan standar apa pun pada bidang, parameter, atau nilai kembalian.

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

Pesan Kustom dengan Interpolasi

Rujuk elemen anotasi dalam pesan menggunakan {elementName}. Gunakan ctx.buildConstraintViolationWithTemplate() untuk menambahkan pesan kustom dengan data dinamis.

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

Batasan Tingkat Kelas

Terapkan batasan pada tingkat kelas untuk memvalidasi beberapa bidang secara bersamaan — berguna untuk aturan lintas bidang seperti konfirmasi kata sandi.

@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 {};
}

Implementasi Validator Tingkat Kelas

Validator menerima seluruh objek. Akses beberapa bidang untuk melakukan validasi lintas bidang.

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;
    }
}

Menggabungkan Batasan

Buat metabatasan dengan menganotasi anotasi kustom menggunakan batasan yang sudah ada. Keduanya akan diterapkan secara otomatis.

@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 {};
}

Mengembalikan Beberapa Pelanggaran

Gunakan ctx.disableDefaultConstraintViolation() dan tambahkan pesan pelanggaran tersendiri untuk setiap masalah yang ditemukan dalam satu proses pemeriksaan validator.

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;
}

Validator yang Dikelola Spring

Karena UniqueEmailValidator dianotasi dengan @Component, Spring menyuntikkan repositori ke dalamnya. Ini hanya berfungsi jika validator diinisialisasi melalui validator Spring, yang dikonfigurasi otomatis oleh Spring Boot.

Menguji Validator Kustom

Uji unit validator secara langsung — tidak diperlukan konteks Spring untuk logika validasi murni. Gunakan Validation.buildDefaultValidatorFactory() untuk pengujian integrasi.

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

Pemeriksaan Singkat

Antarmuka apa yang diimplementasikan oleh validator batasan kustom?

Ringkasan

Buat @interface dengan @Constraint(validatedBy=...). Implementasikan ConstraintValidator. Gunakan @Component untuk injeksi Spring. Batasan tingkat kelas memvalidasi beberapa bidang secara bersamaan. Gabungkan batasan yang sudah ada untuk menghindari duplikasi.

Pertanyaan yang Sering Diajukan

Apakah pelajaran “Anotasi Batasan Khusus” gratis?

Ya — teks lengkap “Anotasi Batasan Khusus” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus Java Academy, upgrade ke CoddyKit PRO. Kursus Java Academy mencakup 4 pelajaran total.

Apa yang akan aku pelajari di “Anotasi Batasan Khusus”?

Buat anotasi @UniqueEmail khusus dengan implementasi ConstraintValidator. Kamu berlatih Java Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.

Apakah aku perlu pengalaman untuk memulai Java Academy?

Tidak diperlukan pengalaman sebelumnya. Java Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 2 dari 4.

Berapa lama pelajaran “Anotasi Batasan Khusus” memakan waktu?

Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.

Bisakah aku menulis dan menjalankan kode dalam pelajaran Java Academy ini?

Ya. Setiap pelajaran Java Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.

Semua pelajaran dalam kursus ini

  1. Validasi Bean: @NotNull, @Size, @Pattern
  2. Anotasi Batasan Khusus
  3. Penanganan Pengecualian Global dengan @ControllerAdvice
  4. Detail Masalah RFC 7807 dan Respons Error yang Konsisten
← Kembali ke Java Academy