[JAVA] Contrôle d'entrée facile avec Bean Validation!

1.Tout d'abord

Cette fois, je voudrais expliquer la méthode de vérification d'entrée en utilisant Bean Validation.

2. Préparation de la bibliothèque

Ajoutez les bibliothèques requises aux dépendances. javax.el est également ajouté car il est nécessaire pour la résolution des messages de hibernate-validator. La bibliothèque Bean Validation (groupId: javax.validation, artifactId: validation-api) n'est pas décrite, mais elle est automatiquement ajoutée à la dépendance car elle a une dépendance.

pom.xml


  <dependency>
    <groupId>org.hibernate.validator</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>6.0.9.Final</version>
  </dependency>
  <dependency>
    <groupId>org.glassfish</groupId>
    <artifactId>javax.el</artifactId>
    <version>3.0.1-b09</version>
  </dependency>

3. Définition du modèle

Définissez la classe de modèle à vérifier. A ce moment, une annotation correspondant à chaque chèque est ajoutée. Les trois types d'annotations suivants peuvent être ajoutés.

Certaines vérifications nécessitent une limite, telle que «@ Max», qui limite le nombre maximum, mais elle est définie comme un attribut de l'annotation. Les attributs qui peuvent être définis diffèrent pour chaque annotation. Si vous souhaitez modifier le message affiché lorsque la vérification échoue, remplacez-le par l'attribut message. Le message défini dans l'attribut message a la priorité la plus élevée.

Book.java


package com.example.beanvalidation.app;

import java.io.Serializable;
import java.util.Date;

import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Past;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;

public class Book implements Serializable {

    private static final long serialVersionUID = 1L;

    @NotNull
    // @Pattern(regexp = "[0-9,-]+")
    @Pattern(regexp = "[0-9,-]+", message = "Valeur saisie${validatedValue}Est incorrect. Veuillez saisir au format ISBM.")
    private String isbn;

    @NotNull
    @Size(max = 200)
    private String title;

    @Max(9999)
    @Min(1)
    private int pageCount;

    @NotNull
    @Past
    private Date publishedDate;

    // constructor, setter, getter omitted
}

4. Modifier le message d'erreur

«Bean Validation» est un message d'erreur car la spécification dépend de la bibliothèque d'implémentation. Dans ce cas, le message défini par hibernate-validator sera la valeur par défaut. Si vous souhaitez modifier ce message par défaut, vous pouvez le remplacer par ValidationMessages.properties situé directement sous le chemin de classe.

Cette fois, je voudrais changer le message par défaut de «@ Past».

Messages de validation directement sous le chemin de classe_ja.properties (pour le japonais)


# javax.validation.constraints.Past.message=Date entrée${validatedValue}Est incorrect. Veuillez saisir une date passée.
javax.validation.constraints.Past.message=\u5165\u529B\u3055\u308C\u305F\u65E5\u4ED8 ${validatedValue} \u306F\u6B63\u3057\u304F\u3042\u308A\u307E\u305B\u3093\u3002\u904E\u53BB\u65E5\u3092\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044\u3002

(Mise en garde)

5. Utilisation de base

Je voudrais définir différentes valeurs pour la classe Book définie ci-dessus et effectuer une vérification d'entrée. Il est courant d'injecter «Validator» lors de l'utilisation d'un conteneur DI, mais cette fois nous utiliserons une application Java normale avec une méthode «main». Cependant, l'utilisation de «Validator» est la même.

ValidationDemo.java


package com.example.beanvalidation.app;

import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.Date;
import java.util.Set;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;

public class ValidationDemo {

    public static void main(String[] args) {
        // 1. create validator
        ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
        Validator validator = factory.getValidator();

        // 2. create target object
        Book book = createBook();

        // 3. validate
        Set<ConstraintViolation<Book>> constraintViolations = validator
                .validate(book);

        // 4. check result
        int errorCount = constraintViolations.size();
        System.out.println("validate error count : " + errorCount);
        if (errorCount > 0) {
            showErrorDetails(constraintViolations);
        }

        System.out.println("=== demo : validate error ===");
        
        // 2. create target object
        book = createNgBook();

        // 3. validate
        constraintViolations = validator.validate(book);

        // 4. check result
        errorCount = constraintViolations.size();
        System.out.println("validate error count : " + errorCount);
        if (errorCount > 0) {
            showErrorDetails(constraintViolations);
        }
    }

    private static <T> void showErrorDetails(
            Set<ConstraintViolation<T>> constraintViolations) {
        for (ConstraintViolation<T> violation : constraintViolations) {
            System.out.println("----------");
            System.out.println(
                    "MessageTemplate : " + violation.getMessageTemplate());
            System.out.println("Message : " + violation.getMessage());
            System.out.println("InvalidValue : " + violation.getInvalidValue());
            System.out.println("PropertyPath : " + violation.getPropertyPath());
            System.out.println("RootBeanClass : " + violation.getRootBeanClass());
            System.out.println("RootBean : " + violation.getRootBean());
        }
    }

    private static Book createBook() {
        Date publishedDate = Date.from(LocalDateTime.of(2017, 7, 21, 0, 0, 0)
                .toInstant(ZoneOffset.ofHours(9)));
        return new Book("978-4798142470",
                "Une introduction approfondie au développement d'applications Spring Java à l'aide de Spring Framework", 744,
                publishedDate);
    }

    private static Book createNgBook() {
        Date publishedDate = Date.from(LocalDateTime.of(2999, 7, 21, 0, 0, 0)
                .toInstant(ZoneOffset.ofHours(9)));
        return new Book("ERROR-ISBN-9999", null, 0, publishedDate);
    }
}

6. Résultat d'exécution (bonus)

Pour référence, les résultats de l'exécution du programme ci-dessus sont indiqués ci-dessous.

Résultat d'exécution


validate error count : 0
=== demo : validate error ===
validate error count : 4
----------
MessageTemplate : {javax.validation.constraints.Min.message}
Message : must be greater than or equal to 1
InvalidValue : 0
PropertyPath : pageCount
RootBeanClass : class com.example.beanvalidation.app.Book
RootBean : Book [isbn=ERROR-ISBN-9999, title=null, pageCount=0, publishedDate=Sun Jul 21 00:00:00 JST 2999]
----------
MessageTemplate : {javax.validation.constraints.Past.message}
Message :Date d'entrée dim 21 juil 00:00:00 JST 2999 est incorrect. Veuillez saisir une date passée.
InvalidValue : Sun Jul 21 00:00:00 JST 2999
PropertyPath : publishedDate
RootBeanClass : class com.example.beanvalidation.app.Book
RootBean : Book [isbn=ERROR-ISBN-9999, title=null, pageCount=0, publishedDate=Sun Jul 21 00:00:00 JST 2999]
----------
MessageTemplate : {javax.validation.constraints.NotNull.message}
Message : must not be null
InvalidValue : null
PropertyPath : title
RootBeanClass : class com.example.beanvalidation.app.Book
RootBean : Book [isbn=ERROR-ISBN-9999, title=null, pageCount=0, publishedDate=Sun Jul 21 00:00:00 JST 2999]
----------
MessageTemplate :Valeur saisie${validatedValue}Est incorrect. Veuillez saisir au format ISBM.
Message :Valeur entrée ERROR-ISBN-9999 est incorrect. Veuillez saisir au format ISBM.
InvalidValue : ERROR-ISBN-9999
PropertyPath : isbn
RootBeanClass : class com.example.beanvalidation.app.Book
RootBean : Book [isbn=ERROR-ISBN-9999, title=null, pageCount=0, publishedDate=Sun Jul 21 00:00:00 JST 2999]

7. Enfin

Cette fois, j'ai expliqué comment vérifier l'entrée par Bean Validation. Je pense que c'est simple et facile à comprendre car vous pouvez définir les spécifications de vérification d'entrée simplement en ajoutant une annotation de vérification.

Recommended Posts

Contrôle d'entrée facile avec Bean Validation!
Ajouter une validation de bean avec Micronaut (Java)
Créez votre propre validateur avec Bean Validation
Vérification de la saisie du numéro de téléphone
[Java] Vérification de la corrélation sans créer d'annotation par vous-même avec Bean Validation
Validation de JSON avec le schéma JSON
Validation personnalisée avec Spring
(Java) BDD facile avec Spectrum?
Micro service facile avec Spark Framework!
Cartographie de Bean avec MapStruct Partie 1
Vérifier la conformité avec les exercices orientés objet
Vérifiez la valeur CSV avec RSpec
Message de validation de processus avec Decorator
Cartographie Bean avec MapStruct Partie 3
Cartographie de Bean avec MapStruct Partie 2
Comment vérifier les nombres entiers avec ruby
Scraping Web facile avec Jsoup
Introduction facile à la bibliothèque avec Maven!
Vérification de l'environnement passionnant avec mkmf