Maison > Java > javaDidacticiel > le corps du texte

Création d'annotations personnalisées pour la validation dans Spring Boot

WBOY
Libérer: 2024-07-25 01:52:13
original
496 Les gens l'ont consulté

Creating Custom Annotations for Validation in Spring Boot

Création d'annotations personnalisées pour la validation dans Spring Boot

1. Aperçu

Bien que les annotations standard Spring (@NotBlank, @NotNull, @Min, @Size, etc.) couvrent de nombreux cas d'utilisation lors de la validation des entrées utilisateur, il arrive parfois que nous devions créer une logique de validation personnalisée pour un type d'entrée plus spécifique. . Dans cet article, je vais montrer comment créer des annotations personnalisées pour la validation.

2. Configuration

Nous devons ajouter la dépendance spring-boot-starter-validation à notre fichier pom.xml.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>
Copier après la connexion

3. Validation personnalisée au niveau du champ

3.1 Création de l'annotation

Créons des annotations personnalisées pour valider les attributs du fichier, tels que l'extension du fichier, la taille du fichier et le type MIME.

  • Extension de fichier valide
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(
        validatedBy = {FileExtensionValidator.class}
)
public @interface ValidFileExtension {
    String[] extensions() default {};

    String message() default "{constraints.ValidFileExtension.message}";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};
}
Copier après la connexion
  • ValidFileMaxSize
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(
        validatedBy = {FileMaxSizeValidator.class}
)
public @interface ValidFileMaxSize {
    long maxSize() default Long.MAX_VALUE; // MB

    String message() default "{constraints.ValidFileMaxSize.message}";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};
}

Copier après la connexion
  • FileMimeTypeValidator
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(
        validatedBy = {FileMimeTypeValidator.class}
)
public @interface ValidFileMimeType {
    String[] mimeTypes() default {};

    String message() default "{constraints.ValidFileMimeType.message}";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};
}
Copier après la connexion

Décomposons les composants de ces annotations :

  • @Constraint : Spécifie la classe de validateur responsable de la logique de validation.
  • @Target({ElementType.FIELD}) : indique que cette annotation ne peut être appliquée qu'aux champs.
  • message() : Le message d'erreur par défaut si la validation échoue.

3.2 Création du validateur

  • Validateur d'extension de fichier
public class FileExtensionValidator implements ConstraintValidator<ValidFileExtension, MultipartFile> {

    private List<String> extensions;

    @Override
    public void initialize(ValidFileExtension constraintAnnotation) {
        extensions = List.of(constraintAnnotation.extensions());
    }

    @Override
    public boolean isValid(MultipartFile file, ConstraintValidatorContext constraintValidatorContext) {
        if (file == null || file.isEmpty()) {
            return true;
        }
        var extension = FilenameUtils.getExtension(file.getOriginalFilename());
        return StringUtils.isNotBlank(extension) && extensions.contains(extension.toLowerCase());
    }
}
Copier après la connexion
  • FichierMaxSizeValidator
public class FileMaxSizeValidator implements ConstraintValidator<ValidFileMaxSize, MultipartFile> {

    private long maxSizeInBytes;

    @Override
    public void initialize(ValidFileMaxSize constraintAnnotation) {
        maxSizeInBytes = constraintAnnotation.maxSize() * 1024 * 1024;
    }

    @Override
    public boolean isValid(MultipartFile file, ConstraintValidatorContext constraintValidatorContext) {
        return file == null || file.isEmpty() || file.getSize() <= maxSizeInBytes;
    }
}

Copier après la connexion
  • FileMimeTypeValidator
@RequiredArgsConstructor
public class FileMimeTypeValidator implements ConstraintValidator<ValidFileMimeType, MultipartFile> {

    private final Tika tika;
    private List<String> mimeTypes;

    @Override
    public void initialize(ValidFileMimeType constraintAnnotation) {
        mimeTypes = List.of(constraintAnnotation.mimeTypes());
    }

    @SneakyThrows
    @Override
    public boolean isValid(MultipartFile file, ConstraintValidatorContext constraintValidatorContext) {
        if (file == null || file.isEmpty()) {
            return true;
        }
        var detect = tika.detect(TikaInputStream.get(file.getInputStream()));
        return mimeTypes.contains(detect);
    }
}

Copier après la connexion

Ces classes sont des implémentations de l'interface ConstraintValidator et contiennent la logique de validation réelle.
Pour FileMimeTypeValidator, nous utiliserons Apache Tika (une boîte à outils conçue pour extraire les métadonnées et le contenu de nombreux types de documents).

3.3 Application de l'annotation

Créons une classe TestUploadRequest destinée à gérer les téléchargements de fichiers, spécifiquement pour un fichier PDF.

@Data
public class TestUploadRequest {

    @NotNull
    @ValidFileMaxSize(maxSize = 10)
    @ValidFileExtension(extensions = {"pdf"})
    @ValidFileMimeType(mimeTypes = {"application/pdf"})
    private MultipartFile pdfFile;

}

Copier après la connexion
@RestController
@Validated
@RequestMapping("/test")
public class TestController {

    @PostMapping(value = "/upload", consumes = {MediaType.MULTIPART_FORM_DATA_VALUE})
    public ResponseEntity<String> testUpload(@Valid @ModelAttribute TestUploadRequest request) {
        return ResponseEntity.ok("test upload");
    }
}

Copier après la connexion
  • @Target({ElementType.TYPE}) : indique que cette annotation cible une déclaration de type.

4. Validation du niveau de classe personnalisée

Une annotation de validation personnalisée peut également être définie au niveau de la classe pour valider une combinaison de champs au sein d'une classe.

4.1 Création de l'annotation

Créons l'annotation @PasswordMatches pour garantir que deux champs de mot de passe correspondent dans une classe.

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(
        validatedBy = {PasswordMatchesValidator.class}
)
public @interface PasswordMatches {
    String message() default "{constraints.PasswordMatches.message}";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};
}

Copier après la connexion

4.2 Création du validateur

  • Mot de passeDto
public interface PasswordDto {
    String getPassword();

    String getConfirmPassword();
}


Copier après la connexion
  • Mot de passeMatchesValidator
public class PasswordMatchesValidator implements ConstraintValidator<PasswordMatches, PasswordDto> {

    @Override
    public boolean isValid(PasswordDto password, ConstraintValidatorContext constraintValidatorContext) {
        return StringUtils.equals(password.getPassword(), password.getConfirmPassword());
    }
}

Copier après la connexion

L'interface PasswordDto est une interface pour les objets qui contiennent un mot de passe et un champ de confirmation du mot de passe.
La classe PasswordMatchesValidator implémente l'interface ConstraintValidator et contient la logique permettant de valider que les champs de mot de passe et de confirmation du mot de passe correspondent.

4.3 Application de l'annotation

Créons une classe RegisterAccountRequest destinée à gérer les données d'enregistrement des utilisateurs.

@PasswordMatches
@Data
public class RegisterAccountRequest implements PasswordDto {

    @NotBlank
    private String username;

    @NotBlank
    @Email
    private String email;

    @NotBlank
    @ToString.Exclude
    private String password;

    @NotBlank
    @ToString.Exclude
    private String confirmPassword;
}

Copier après la connexion
@RestController
@Validated
@RequestMapping("/auth")
public class AuthController {

    @PostMapping("/register")
    public ResponseEntity<String> register(@RequestBody @Valid RegisterAccountRequest request) {
        return ResponseEntity.ok("register success");
    }
}

Copier après la connexion

5. Résumé

Dans ce court article, nous avons découvert à quel point il est simple de créer des annotations personnalisées pour vérifier un champ ou une classe. Le code de cet article est disponible sur mon Github.

  • spring-boot-microservices
  • service-utilisateur

6. Références

  • Baeldung. (s.d.). Validateur personnalisé Spring MVC. Récupéré à partir de https://www.baeldung.com/spring-mvc-custom-validator

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:dev.to
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal