Skip to content

Formulaires Spring

Le framework Spring nous offre énormément de fonctionnalités, l'une d'entre elle est une intégration simplifiée des formulaires. Les formulaires Spring sont basés sur l'objet Model et la liaison avec un paramètre modelAttribute.

Pour utiliser les formulaires Spring, il faut ajouter la directive de taglib suivante à la page JSP

<%@ taglib prefix = "form" uri ="http://www.springframework.org/tags/form"%>

Ce taglib nous offre plusieurs balises pour écrire les formulaires. Ces balises remplacent les balises HTML qu'on utiliserait normalement. Voici quelques exemples:

Balise HTML Équivalent du taglib
<form> <form:form>
<input> <form:input>
<label> <form:label>
<input type="password"> <form:password>
<select> <form:select>
<input type="checkbox"> <form:checkbox>

Différence avec les balises HTML

Bien que ces balises remplacent les balises HTML, elles se comportent un peu différemment. On pourra généralement utiliser les attributs HTML standard en combinaison avec des attributs spécifiques. Par exemple pour ajouter une classe CSS à une balise, on utilisera cssClass au lieu de class.

Configuration d'un formulaire

Pour pouvoir utiliser un formulaire Spring, il faudra utiliser l'objet Model et lui donner un objet qui correspond au formulaire. Par exemple, pour ajouter un produit dans une liste de produits, il faudra envoyer un objet Produit et l'associer au formulaire. Dans la méthode POST, on pourra facilement récupérer un objet Produit complètement formé.

Dans le contrôleur

@GetMapping("/produits/ajouter")
public String formulaireAjouter(Model model) {
    Produit produit = new Produit();
    model.addAttribute("produit", produit);
    return "formulaire-produit";
}

@PostMapping("/produits/ajouter")
public String ajouterProduit(@ModelAttribute("produit") Produit produit) {
    // Le produit issu des paramètres est un objet complet dont les propriétés ont été remplies par le formulaire
    produitService.ajouterProduit(produit);
    return "redirect:/produits";
}

Dans la vue

<c:url var= "postUrl" value="/produits/ajouter" />
<form:form method="post" action="${postUrl}" modelAttribute="produit">
 <form:label path="nom" cssClass="mes classes css">Nom</form:label>
 <form:input path="nom" type="text" cssClass="mes classes css" />
</form:form>

Remarquez qu'au lieu de l'attribut name, on utilise plutôt l'attribut path. C'est une spécificité des balises de formulaire Spring.

Documentation officielle de Spring sur le taglib form

Validation côté serveur

Du côté serveur, on peut utiliser la validation de Spring. Pour cela, au fichier pom.xml, ajouter la dépendence suivante.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>

Il est aussi possible d'ajouter cette dépendence à partir du menu de sélection lors de la création de projet. Elle se trouve dans la catégorie I/O et se nomme Validation.

Cette librairie nous permet d'ajouter des décorateurs aux propriétés des classes que l'on crée pour spécifier leur état de validité. Parmi ces décorateurs on retrouvera par exemple:

  • @NotNull
  • @Length
  • @Min
  • @Max
  • @Email
  • @Pattern

Ces décorateurs nous permettrons également d'ajouter un message en cas d'erreur de validation. Par exemple:

public class Produit {
    @NotNull(message = "Veuillez saisir le prix")
    @Min(value = 0, message = "Le prix doit être une valeur positive")
    private float prix;
}

Dans le contrôleur, dans la méthode qui recevra les résultats du formulaire on ajoutera un peu de configuration supplémentaire.

@PostMapping("/produits/ajouter")
public String ajouterProduit(@Valid @ModelAttribute("produit") Produit produit, BindingResult bindingResult) {

    /* Si des attriuts sont invalides, on renvoie le formulaire avec les messages
       d'erreur à l'utilisateur. Le formulaire sera dans le même état que lorsque
       l'utilisateur en a fait la soumission.
    */
    if (bindingResult.hasErrors()) {
        return "formulaire-produit";
    }

    produitService.ajouterProduit(produit);
    return "redirect:/produits";
}

Dans les pages JSP, pour afficher les erreurs on ajoutera la balise <form:errors>

<c:url var= "postUrl" value="/produits/ajouter" />
<form:form method="post" action="${postUrl}" modelAttribute="produit">
 <form:label path="nom" cssClass="mes classes css">Nom</form:label>
 <form:input path="nom" type="text" cssClass="mes classes css" />
 <form:errors path="nom" cssClass="mes classes css">
</form:form>

Validation côté client

Les formulaires Spring ne nous offrent malheureusement pas une façon simple de faire la validation des formulaires avant leur soumission. On devra se tourner vers des scripts personalisés pour le faire. On peut donc se tourner vers jQuery et le plugin jQuery validation pour nous aider.

Balises script à ajouter

Au moment d'écrire ceci, les versions le plus à jour sont 3.7.1 pour jQuery et 1.21.0 pour le plugin de validation. On peut donc ajouter aux pages les balises script suivantes:

<script src="https://code.jquery.com/jquery-3.7.1.min.js" integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.21.0/jquery.validate.min.js"></script>

Pour utiliser jQuery validation, assurez vous d'avoir donné un id au formulaire à valider, pour y faire référence dans le script de validation.

Créez ensuite un fichier JavaScript pour contenir votre script de validation. (Rappel, placez ce fichier dans le dossier /src/main/resources/static/javascript)

$(document).ready(function () {
    $("#formProduit").validate({
        // vos règles de validation
        rules: {

        },
        // les messages d'erreur
        messages: {

        },
        // Le type d'élément à ajouter pour le message d'erreur
        errorElement: "div",
        // Où ajouter l'élément
        errorPlacement: function (error, element) {
            error.addClass("invalid-feedback");
            error.insertAfter(element);
        },
        // Ajoute une classe lorsque l'erreur est relevée
        highlight: function (element) {
            $(element).addClass("is-invalid");
        },
        // Retire une classe lorque l'erreur est réglée
        unhighlight: function (element) {
            $(element).removeClass("is-invalid");
        }
    });
});

Dans la section rules on peut ajouter un élément qui correspond à l'attribut path pour indiquer le champ à valider. On peut ensuite mettre plusieurs règles à valider avec des messages correspondants.

rules : {
    prix : {
        required: true,
        min: 0
    }
},
messages : {
    prix : {
        required : "Le pris est requis",
        min : "La valeur ne peut pas être moin que 0"
    }
}

N'oubliez pas d'ajouter votre script de validation à votre page JSP!

<script src="<c:url value="/javascript/validation.js"/>"></script>