2026-10-05

SLF4J(I): Connected with provider of type [ch.qos.logback.classic.spi.LogbackServiceProvider]
Où sont définies les contraintes ?
@NotNull, @Size, @EmailLe rôle du validateur
Contraintes personnalisées
%%compile fr/univtln/bruno/Person.java
package fr.univtln.bruno;
import lombok.AllArgsConstructor;
import jakarta.validation.constraints.*;
@AllArgsConstructor(staticName = "of")
public class Person {
@NotNull(message = "Name cannot be null")
private String name;
@AssertTrue
private boolean active;
@Size(min = 18, max = 100,
message = "Description must be between {min} and {max} characters")
private String description;
@Min(value = 18, message = "Age should not be less than {value}")
@Max(value = 150, message = "Age should not be greater than {value}")
private int age;
@Email(message = "Email '${validatedValue}' is not valid")
private String email;
}%%compile fr/univtln/bruno/X.java
package fr.univtln.bruno;
import jakarta.validation.constraints.*;
import jakarta.validation.executable.ValidateOnExecution;
@ValidateOnExecution(type=jakarta.validation.executable.ExecutableType.ALL)
public class X {
private String value;
public X(@NotNull @Size(min=6) String name) {this.value = value;}
@Size(min=3)
public String update(@NotNull @Size(min=1) String a,
@NotNull @Size(min=1) String b) { return value=a+b;}
}16:15:58.483 [IJava-executor-0] INFO o.h.validator.internal.util.Version -- HV000001: Hibernate Validator 8.0.1.Final
ConstraintViolationImpl{interpolatedMessage='Email 'p@' is not valid', propertyPath=email, rootBeanClass=class fr.univtln.bruno.Person, messageTemplate='Email '${validatedValue}' is not valid'}
ConstraintViolationImpl{interpolatedMessage='Description must be between 18 and 100 characters', propertyPath=description, rootBeanClass=class fr.univtln.bruno.Person, messageTemplate='Description must be between {min} and {max} characters'}
@NotNull value is not null.@AssertTrue value is true.@Size size between the attributes min and max (String, Collection, Map, and Array).@Min validates no smaller than the value attribute.@Max validates no larger than the value attribute.@Email validates valid email address.@NotEmpty not null nor empty (String, Collection, Map or Array).@NotBlank ot null or whitespace (Text only).@Positive and @PositiveOrZero trictly positive, or positive including 0.@Negative and @NegativeOrZero apply to numeric values and validate that they are strictly negative, or negative including 0 (numeric only).@Past and @PastOrPresent date value is in the past or the past including the present.@Future and @FutureOrPresent date value is in the future, or in the future including the present.@Size(min=2, max=10) pour spécifier une taille minimale et maximale.message permet de définir un message d’erreur personnalisé en cas de violation.
{} pour insérer des valeurs dynamiques dans le message.@Size(min=2, message="{javax.validation.constraints.Size.message}")%%compile fr/univtln/bruno/Message.java
package fr.univtln.bruno;
import jakarta.validation.constraints.*;
import lombok.*;
import java.util.List;
import java.util.Optional;
import java.time.LocalDate;
@Data(staticConstructor="of")
public class Message {
private final List<@NotBlank String> lines;
private final Optional<@Past LocalDate> date;
}lines[1].<list element> must not be blank
date must be a past date
@Valid
@Valid permet de déclencher la validation de propriétés qui sont elles-mêmes des objets.[ConstraintViolationImpl{interpolatedMessage='must not be empty', propertyPath=maitre.name, rootBeanClass=class fr.univtln.bruno.Chien, messageTemplate='{jakarta.validation.constraints.NotEmpty.message}'}]
Le rôle du Validator
Validator est responsable de l’exécution des règles de validation définies sur un objet.Invocation du Validator
Invocation manuelle: Vous pouvez instancier un Validator et l’utiliser pour valider un objet à tout moment.
Invocation automatique: De nombreux frameworks (JPA, JAX-RS, etc.) intègrent Bean Validation et appellent automatiquement le Validator dans des contextes spécifiques (par exemple, avant de persister une entité JPA).
Exploration des contraintes
Validator retourne un ensemble de violations en cas d’échec de la validation.[]
BeanDescriptorImpl{class='Chien'}
Messages par défaut et personnalisation
message.{value}) pour afficher la valeur de la propriété en erreur.Internationalisation
resources).%%compile fr/univtln/bruno/CheckCase.java
package fr.univtln.bruno;
import jakarta.validation.Constraint;
import jakarta.validation.Payload;
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
@Target({ FIELD, METHOD, PARAMETER, ANNOTATION_TYPE, TYPE_USE })
@Retention(RUNTIME)
@Constraint(validatedBy = CheckCaseValidator.class)
@Documented
@Repeatable(CheckCase.List.class)
public @interface CheckCase {
String message() default "{fr.univtln.bruno.beanvalidation.CheckCase.message}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
CaseMode value();
@Target({ FIELD, METHOD, PARAMETER, ANNOTATION_TYPE })
@Retention(RUNTIME)
@Documented
@interface List {
CheckCase[] value();
}
}/tmp/jupyterJava/fr/univtln/bruno/CheckCase.java:10: error: cannot find symbol
@Constraint(validatedBy = CheckCaseValidator.class)
^
symbol: class CheckCaseValidator
1 error
%%compile fr/univtln/bruno/CheckCaseValidator.java
package fr.univtln.bruno;
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
public class CheckCaseValidator implements ConstraintValidator<CheckCase, String> {
private CaseMode caseMode;
@Override
public void initialize(CheckCase constraintAnnotation) {
this.caseMode = constraintAnnotation.value();
}
@Override
public boolean isValid(String object, ConstraintValidatorContext constraintContext) {
if ( object == null ) {
return true;
}
if ( caseMode == CaseMode.UPPER ) {
return object.equals( object.toUpperCase() );
}
else {
return object.equals( object.toLowerCase() );
}
}
}x {fr.univtln.bruno.beanvalidation.CheckCase.message}
y {fr.univtln.bruno.beanvalidation.CheckCase.message}
Une contrainte de classe s’applique à l’ensemble d’un objet et vérifie qu’il respecte certaines règles globales.
/tmp/jupyterJava/fr/univtln/bruno/PersonDTO.java:4: error: cannot find symbol
@PersonValidation
^
symbol: class PersonValidation
1 error
%%compile fr/univtln/bruno/PersonValidation.java
package fr.univtln.bruno;
import jakarta.validation.Constraint;
import jakarta.validation.Payload;
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
@Target({ TYPE })
@Retention(RUNTIME)
@Constraint(validatedBy = PersonValidator.class)
@Documented
public @interface PersonValidation {
String message() default "{fr.univtln.bruno.beanvalidation.PersonDTO.message}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
//no value
}/tmp/jupyterJava/fr/univtln/bruno/PersonValidation.java:10: error: cannot find symbol
@Constraint(validatedBy = PersonValidator.class)
^
symbol: class PersonValidator
1 error
%%compile fr/univtln/bruno/PersonValidator.java
package fr.univtln.bruno;
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
public class PersonValidator implements ConstraintValidator<PersonValidation, PersonDTO> {
@Override
public void initialize(PersonValidation constraintAnnotation) {
}
@Override
public boolean isValid(PersonDTO person, ConstraintValidatorContext constraintContext) {
if (person==null) return false;
if ((person.id()>=1) || (person.id()<=100))
if (person.name().isBlank() && person.nickname().isBlank()) return false;
return true;
}
}[ConstraintViolationImpl{interpolatedMessage='{fr.univtln.bruno.beanvalidation.PersonDTO.message}', propertyPath=, rootBeanClass=class fr.univtln.bruno.PersonDTO, messageTemplate='{fr.univtln.bruno.beanvalidation.PersonDTO.message}'}]
Des contraintes peuvent être regroupées pour former des ensembles de règles à appliquer simultanément.
%%compile fr/univtln/bruno/SimpleUser.java
package fr.univtln.bruno;
import lombok.*;
import jakarta.validation.constraints.*;
import jakarta.validation.constraints.Pattern;
@Data(staticConstructor="of")
public class SimpleUser {
@NotNull
@Pattern(regexp = "[a-zA-Z0-9]+", message = "only digits and letters")
@Size(min = 6, max = 10, message = "must have between {min} and {max} characters")
private final String login;
@NotNull
@Pattern(regexp = "[a-zA-Z0-9]+", message = "only digits and letters")
@Size(min = 6, max = 10, message = "must have between {min} and {max} characters")
private final String nickname;
}login must have between 6 and 10 characters
nickname must have between 6 and 10 characters
%%compile fr/univtln/bruno/ValidIdentifier.java
package fr.univtln.bruno;
import jakarta.validation.Constraint;
import jakarta.validation.ReportAsSingleViolation;
import jakarta.validation.constraints.*;
import java.lang.annotation.*;
import jakarta.validation.Payload;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
@NotNull
@Pattern(regexp = ".*\\d.*", message = "must contain at least one numeric character")
@Size(min = 6, max = 32, message = "must have between 6 and 32 characters")
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = {})
@ReportAsSingleViolation
public @interface ValidIdentifier {
String message() default "field should have a valid length and contain numeric character(s).";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}%%compile fr/univtln/bruno/SimpleUserBis.java
package fr.univtln.bruno;
import lombok.*;
import jakarta.validation.constraints.*;
import jakarta.validation.constraints.Pattern;
@Data(staticConstructor="of")
public class SimpleUserBis {
@ValidIdentifier
private final String login;
@ValidIdentifier
private final String nickname;
}nickname field should have a valid length and contain numeric character(s).
login field should have a valid length and contain numeric character(s).
Lire le guide de référence.
E. Bruno - Java Bean validation