Dernière modification : 24/08/2022

Validations personnalisées - Spring Rest

Dans cet article nous allons voir comment utiliser des validations personnalisées avec Spring Boot. Les technologies utilisées sont les suivantes :

  • Spring Boot 2
  • Spring
  • Maven
  • Java 11

Prérequis : Nous nous baserons sur l'article Spring Boot - Validation et le contenu associé.

Nous allons créer une annotation sur le champs registration de la classe Car. La validation aura pour but de véririfier que le contenu du champ registration contient au moins un tiret.

1. Création de l'annotation

Création de l'annotation qui sera positionné sur le champ registration :

@Target( { ElementType.METHOD, ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = RegistrationValidator.class)
@Documented
public @interface RegistrationConstraint {

    String message() default "Register not contain '-'";

    Class[] groups() default {};

    Class[] payload() default {};
}

2. Création du validator

Création du validator qui sera exécuté en ayant pour information le champ registration :

public class RegistrationValidator implements ConstraintValidator {
    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        return value == null ? false : value.contains("-");
    }
}

3. Mise à jour de l'entité

Mise à jour de l'entité Car afin d'ajouter l'annotation précédemment créé :

@Entity
public class Car {
	@Id
	@GeneratedValue
	private Long id;
	
        @NotEmpty(message = "Please provide a model")
	private String model;
	
        @RegistrationConstraint
        @NotEmpty(message = "Please provide a registration")
	private String registration;
        // ...
}

4. Test

Nous venons de créer une annotation et la validation associé que nous avons affecté au champ registration de l'entité Car. Il est désormais possible de réaliser quelques tests.

Validation en erreur :

$ curl -v -X POST localhost:8080/car -H "Content-type:application/json" -d "{\"model\":\"ABC\",\"registration\":\"ABC\"}"
*   Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 8080 (#0)
> POST /car HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.64.1
> Accept: */*
> Content-type:application/json
> Content-Length: 36
> 
* upload completely sent off: 36 out of 36 bytes
< HTTP/1.1 400 
< Content-Type: application/json
< Transfer-Encoding: chunked
< Date: Sat, 09 Jan 2021 11:09:57 GMT
< Connection: close
< 
* Closing connection 0
{"timestamp":"2021-01-09T11:09:57.684+00:00","status":400,"errors":["Register not contain '-'"]}%

Validation sans erreur :

$ curl -v -X POST localhost:8080/car -H "Content-type:application/json" -d "{\"model\":\"ABC\",\"registration\":\"AB-C\"}"
*   Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 8080 (#0)
> POST /car HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.64.1
> Accept: */*
> Content-type:application/json
> Content-Length: 37
> 
* upload completely sent off: 37 out of 37 bytes
< HTTP/1.1 200 
< Content-Type: application/json
< Transfer-Encoding: chunked
< Date: Sat, 09 Jan 2021 11:11:04 GMT
< 
* Connection #0 to host localhost left intact
{"id":2,"model":"ABC","registration":"AB-C"}* Closing connection 0

La validation customisée est bien fonctionnelle.