Spring MVC et l’annotation @ModelAttribute

Spring MVC et l'annotation @ModelAttribute

1. Vue d'ensemble

L'une des annotationsSpring-MVC les plus importantes est l'annotation@ModelAttribute.

Le@ModelAttribute est une annotation qui lie un paramètre de méthode ou une valeur de retour de méthode à un attribut de modèle nommé, puis l'expose à une vue Web.

Dans l'exemple suivant, nous démontrerons la convivialité et la fonctionnalité de l'annotation, à travers un concept commun: un formulaire soumis par un employé d'une entreprise.

Lectures complémentaires:

Modèle, Carte modèle et Vue modèle dans Spring MVC

Découvrez les interfacesModel,ModelMap etModelView fournies par Spring MVC.

Read more

Spring @RequestParam Annotation

Un guide détaillé de l'annotation @RequestParam de Spring

Read more

2. Les@ModelAttribute en profondeur

Comme l'a révélé le paragraphe d'introduction,@ModelAttribute peut être utilisé soit comme paramètre de méthode, soit au niveau de la méthode.

2.1 At the Method Level

Lorsque l'annotation est utilisée au niveau de la méthode, elle indique que le but de cette méthode est d'ajouter un ou plusieurs attributs de modèle. Ces méthodes prennent en charge les mêmes types d'arguments que les méthodes@RequestMapping mais qui ne peuvent pas être mappées directement aux requêtes.

Jetons un coup d'œil à un exemple rapide ici pour commencer à comprendre comment cela fonctionne:

@ModelAttribute
public void addAttributes(Model model) {
    model.addAttribute("msg", "Welcome to the Netherlands!");
}

Dans l'exemple, nous montrons une méthode qui ajoute un attribut nommémsg à tous lesmodel définis dans la classe de contrôleur.

Bien sûr, nous verrons cela en action plus tard dans l'article.

En règle générale, Spring-MVC appelle toujours cette méthode avant d’appeler une méthode de gestionnaire de demandes. That is, @ModelAttribute methods are invoked before the controller methods annotated with @RequestMapping are invoked. La logique derrière la séquence est que, l'objet modèle doit être créé avant que tout traitement ne démarre dans les méthodes du contrôleur.

Il est également important que vous annotiez la classe respective en tant que@ControllerAdvice. Ainsi, vous pouvez ajouter des valeurs enModel qui seront identifiées comme globales. Cela signifie en fait que pour chaque demande, une valeur par défaut existe, pour chaque méthode de la partie réponse.

2.2 As a Method Argument

Lorsqu'il est utilisé comme argument de méthode, il indique que l'argument doit être extrait du modèle. Lorsqu'il n'est pas présent, il doit d'abord être instancié puis ajouté au modèle, puis une fois présent dans le modèle, les champs d'arguments doivent être renseignés à partir de tous les paramètres de requête portant des noms correspondants.

Dans l'extrait de code qui suit, l'attribut de modèleemployee est rempli avec les données d'un formulaire soumis au point de terminaisonaddEmployee. Spring MVC fait cela en coulisse avant d’appeler la méthode submit:

@RequestMapping(value = "/addEmployee", method = RequestMethod.POST)
public String submit(@ModelAttribute("employee") Employee employee) {
    // Code that uses the employee object

    return "employeeView";
}

Plus loin dans cet article, nous verrons un exemple complet de la façon d'utiliser l'objetemployee pour remplir le modèleemployeeView.

Ainsi, il lie les données de formulaire avec un bean. The controller annotated with @RequestMapping can have custom class argument(s) annotated with @ModelAttribute.

C'est ce que l'on appelle communément la liaison de données dans Spring-MVC, un mécanisme commun qui vous évite d'avoir à analyser chaque champ de formulaire individuellement.

3. Exemple de formulaire

Dans cette section, nous fournirons l'exemple mentionné dans la section vue d'ensemble: un formulaire très basique qui invite un utilisateur (employé d'une entreprise, dans notre exemple spécifique), à ​​saisir certaines informations personnelles (en particuliername etid). Une fois la soumission terminée et sans aucune erreur, l'utilisateur s'attend à voir les données précédemment soumises, affichées sur un autre écran.

3.1 The View

Commençons par créer un formulaire simple avec des champs d'identifiant et de nom:


    Name
    

    Id
    

    

3.2 The Controller

Voici la classe de contrôleur dans laquelle la logique de la vue susmentionnée est implémentée:

@Controller
@ControllerAdvice
public class EmployeeController {

    private Map employeeMap = new HashMap<>();

    @RequestMapping(value = "/addEmployee", method = RequestMethod.POST)
    public String submit(
      @ModelAttribute("employee") Employee employee,
      BindingResult result, ModelMap model) {
        if (result.hasErrors()) {
            return "error";
        }
        model.addAttribute("name", employee.getName());
        model.addAttribute("id", employee.getId());

        employeeMap.put(employee.getId(), employee);

        return "employeeView";
    }

    @ModelAttribute
    public void addAttributes(Model model) {
        model.addAttribute("msg", "Welcome to the Netherlands!");
    }
}

Dans la méthodesubmit(), nous avons un objetEmployee lié à nosView. Pouvez-vous voir le pouvoir de cette annotation? Vous pouvez mapper vos champs de formulaire sur un modèle d'objet aussi simplement. Dans la méthode, nous récupérons les valeurs du formulaire et les définissons surModelMap.

À la fin, nous retournonsemployeeView, ce qui signifie que le fichier JSP respectif va être appelé en tant que représentant deView.

De plus, il existe également une méthodeaddAttributes(). Son but est d'ajouter des valeurs dans lesModel qui seront identifiées globalement. C'est-à-dire qu'une valeur par défaut sera renvoyée sous forme de réponse pour chaque demande à chaque méthode de contrôleur. Nous devons également annoter la classe spécifique en tant que@ControllerAdvice.

3.3 The Model

Comme mentionné précédemment, l'objetModel est très simpliste et contient tout ce qui est requis par les attributs «front-end». Voyons maintenant un exemple:

@XmlRootElement
public class Employee {

    private long id;
    private String name;

    public Employee(long id, String name) {
        this.id = id;
        this.name = name;
    }

    // standard getters and setters removed
}

3.4 Wrap Up

Le@ControllerAdvice assiste un contrôleur et en particulier, les méthodes@ModelAttribute qui s'appliquent à toutes les méthodes@RequestMapping. Bien sûr, notre méthodeaddAttributes() sera la toute première à être exécutée, avant le reste des méthodes@RequestMapping.

En gardant cela à l'esprit et après l'exécution desubmit() etaddAttributes(), nous pourrions simplement y faire référence dans lesView renvoyés par la classeController, en mentionnant leur prénom à l'intérieur d'un duo d'accolades dollarisé, comme par exemple${name}.

3.5 Results View

Imprimons maintenant ce que nous avons reçu du formulaire:

${msg}

Name : ${name} ID : ${id}

4. Conclusion

Dans ce didacticiel, nous avons étudié l'utilisation de l'annotation@ModelAttribute, à la fois pour les arguments de méthode et les cas d'utilisation au niveau de la méthode.

L'implémentation de ce tutoriel simple peut être trouvée dans le projetgithub - il s'agit d'un projet basé sur Maven, il devrait donc être facile à importer et à exécuter tel quel.