Mukautetut rajoiteannotaatiot
Luo mukautettu @UniqueEmail-annotaatio ConstraintValidator-toteutuksen avulla.
Mukautetut rajoiteannotaatiot on ilmainen Java Academy-oppitunti CoddyKitissä. Tämä on oppitunti 2/4. Voit lukea koko oppitunnin alta ilmaiseksi ja harjoitella sen jälkeen käytännössä selaimessa sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla. Oppitunti kuuluu Java Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. Java Academy-kurssilla on yhteensä 4 oppituntia.
Kun vakiorajoitteet eivät riitä
Bean Validationin vakioannotaatiot kattavat yleiset käyttötapaukset. Toimialakohtaisia sääntöjä varten, kuten yksilöllisen sähköpostiosoitteen, kelvollisen IBAN-numeron tai salasanan vahvuuden tarkistamiseen, luokaa mukautettuja rajoiteannotaatioita.
Rajoiteannotaation määrittäminen
Luokaa annotaatio, jossa on @Constraint(validatedBy = ...), pakolliset message-, groups- ja payload-elementit sekä asianmukaiset retention- ja target-määritteet.
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-toteutuksen luominen
Toteuttakaa ConstraintValidator<UniqueEmail, String>. initialize-metodi lukee annotaation elementit, ja isValid suorittaa varsinaisen tarkistuksen.
@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);
}
}Mukautetun rajoitteen käyttäminen
Käyttäkää annotaatiota minkä tahansa vakiorajoitteen tapaan kentässä, parametrissa tai palautusarvossa.
public record CreateUserRequest(
@NotBlank
String name,
@NotBlank @Email @UniqueEmail
String email
) {}Mukautettu viesti interpoloinnilla
Viitatkaa annotaation elementteihin viestissä käyttämällä muotoa {elementName}. Käyttäkää ctx.buildConstraintViolationWithTemplate()-metodia mukautettujen, dynaamisia tietoja sisältävien viestien lisäämiseen.
@Constraint(validatedBy = RangeValidator.class)
public @interface InRange {
int min() default 0;
int max() default 100;
String message() default "Must be between {min} and {max}";
// ...
}Luokkatason rajoite
Käyttäkää rajoitetta luokkatasolla useiden kenttien tarkistamiseen yhdessä. Tämä sopii esimerkiksi salasanan vahvistamisen kaltaisiin kenttien välisiin sääntöihin.
@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 {};
}Luokkatason validatorin toteutus
Validatori saa koko olion. Käsitelkää useita kenttiä kenttien välisten sääntöjen tarkistamiseksi.
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;
}
}Rajoitteiden yhdistäminen
Luokaa metarajoite merkitsemällä mukautettu annotaatio olemassa olevilla rajoitteilla. Molemmat rajoitteet otetaan automaattisesti käyttöön.
@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 {};
}Useiden virheiden palauttaminen
Kutsukaa ctx.disableDefaultConstraintViolation()-metodia ja lisätkää jokaisesta löydetystä ongelmasta oma virheviesti yhden validatorin suorituksen aikana.
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;
}Springin hallinnoimat validatorit
Koska UniqueEmailValidator on merkitty @Component-annotaatiolla, Spring injektoi repositoriot siihen. Tämä toimii vain, jos validator käynnistetään Springin validatorin kautta, minkä Spring Boot kytkee automaattisesti käyttöön.
Mukautettujen validatorien testaaminen
Testatkaa validatorit suoraan yksikkötesteillä — puhtaan validointilogiikan testaamiseen ei tarvita Spring-kontekstia. Käyttäkää Validation.buildDefaultValidatorFactory()-metodia integraatiotesteissä.
Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
CreateUserRequest req = new CreateUserRequest("", "bad-email", null);
Set<ConstraintViolation<CreateUserRequest>> violations = validator.validate(req);
System.out.println(violations.size()); // 3Pikatarkistus
Minkä rajapinnan mukautettu rajoitevalidatori toteuttaa?
Kertaus
Luokaa @interface, jossa on @Constraint(validatedBy=...). Toteuttakaa ConstraintValidator. Käyttäkää @Component-annotaatiota Spring-injektiota varten. Luokkatason rajoitteet tarkistavat useita kenttiä yhdessä. Yhdistäkää olemassa olevia rajoitteita päällekkäisen koodin välttämiseksi.
Opi Java tekoälytuutorin avulla — ilmaiseksi
Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.
- Kurssit
- 104
- Oppitunnit
- 374
Usein kysytyt kysymykset
Onko oppitunti ”Mukautetut rajoiteannotaatiot” ilmainen?
Kyllä – oppitunnin ”Mukautetut rajoiteannotaatiot” koko tekstin voi lukea täällä verkossa ilmaiseksi. Jos haluat harjoitella interaktiivisesti sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla sekä avata koko Java Academy-kurssin, päivitä CoddyKit PROhon. Java Academy-kurssilla on yhteensä 4 oppituntia.
Mitä opin oppitunnilla ”Mukautetut rajoiteannotaatiot”?
Luo mukautettu @UniqueEmail-annotaatio ConstraintValidator-toteutuksen avulla. Harjoittelet Java Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.
Tarvitsenko kokemusta aloittaakseni Java Academy-opiskelun?
Aiempi kokemus ei ole tarpeen. CoddyKitin Java Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 2/4.
Kuinka kauan ”Mukautetut rajoiteannotaatiot”-oppitunnin suorittaminen kestää?
Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.
Voinko kirjoittaa ja suorittaa koodia tällä Java Academy-oppitunnilla?
Kyllä. Jokainen Java Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.
Kaikki tämän kurssin oppitunnit
- Bean Validation: @NotNull, @Size, @Pattern
- Mukautetut rajoiteannotaatiot
- Poikkeusten keskitetty käsittely @ControllerAdvice-annotaatiolla
- RFC 7807:n ongelmatiedot ja yhdenmukaiset virhevastaustaukset