lundi 26 novembre 2012

Java Serveur App 13 : AJAX


AJAX

AJAX signifie:
  • Asynchronous : il s'agit d'appels asynchrones vers le serveur. La page ne se recharge pas.
  • Javascript : les appels sont initiés par Javascript ce qui permet de modifier la page dans la navigateur avec le résultat de la requête.
  • And
  • XML : les échanges entre le client et le serveur se font avec du XML. Cependant XML est de moins en moins utilisé, des formats comme JSON ou YAML sont de plus en plus utilisés.
Dans notre application il va falloir:
  • Faire l'appel au serveur depuis Javascript, nous verrons que JQuery propose une alternative très simple et souple.
  • Effectuer l'aller retour au serveur et voir comment répondre à une requête avec une chaine de caractères et pas une page JSP complète.
  • Récupérer le résultat dans Javascript et effectuer les modifications nécessaires dans la page
Exemple de la suppression d'un élément d'une liste

Notre exemple est une liste chargée dans le navigateur. Dans l'ordre, la transaction AJAX va comporter les étapes suivantes:

  1. Le clic sur le bouton de suppression déclenche une fonction Javascript qui lance un appel au serveur sur l'URL "ajaxSupprimer" avec un paramètre id pour l'objet.
  2. La serveur reçoit cet identifiant, supprime l'objet correspondant et répond "done" au client s'il a réussi à supprimer, "error" sinon.
  3. Le client effectue la suppression de la ligne en Javascript.
Le code client est le suivant


<%@page import="java.util.List"%>
<%@page import="com.deguet.Controller"%>
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Demo AJAX</title>
 <script src="http://code.jquery.com/jquery-latest.js"></script>
        <script>
            function supprimer(element){
                console.log("Suppression AJAX de "+element);
                $.ajax({
                   url: 'ajaxSupprimer?id='+element,
                   success: function(data) {
                    $("#"+element).remove();
                   }
                });
            }
        </script>
    </head>
    <body>
        <h1>Exemple AJAX</h1>
        <table>
        <%
            Controller.initElements(request);
            List<String> elements = (List<String>) session.getAttribute("elements");
            System.out.println("La liste vaut " + elements);
            for (String element : elements){
                %>
                 <tr id="<%= element%>">
                  <td><%= element%></td>
                  <td> <button  onclick="supprimer('<%= element%>');" >X</button>  </td>
                 </tr>
                <%
            }
        %>
        </table>
    </body>
</html>


Quelques explications:

  • Dans la boucle for, on crée chaque ligne de notre tableau avec un id dans le DOM pour pouvoir facilement la supprimer plus tard. La fonction supprimer est appelé sur le onclick avec cet id.
  • Plus haut, on voit la fonction supprimer responsable de l'appel AJAX ($.ajax() de JQuery) auquel on fournit l'URL ("ajaxSupprimer?id=5" si l'id est 5) ainsi que la fonction à exécuter en cas de succès (puisque l'appel est asynchrone). Le paramètre "data" contient alors la réponse du serveur.
  • La fonction de "success" va simplement supprimer le tr (ligne dans notre tableau) avec l'id correspondant.


Maintenant côté serveur, notre contrôleur va prendre en charge le motif URL ajaxSupprimer:


if (action.equals("/ajaxSupprimer")){
 String id = request.getParameter("id");
 System.out.println("Suppression AJAX " + id);
 List<String> elements = (List<String>) request.getSession().getAttribute("elements");
 if (elements != null && elements.contains(id)) {
  elements.remove(id);
  response.getWriter().println("done");
 } else {
  response.getWriter().println("error");
 }
 return;
}

Les différentes étapes sont :

  • Récupérer les objets nécessaires: ici l'identifiant et la liste à modifier.
  • Déterminer si l'opération est possible, c'est le sens du "if (elements != null .... )"
  • Effectuer l'opération quand c'est possible.
  • Renvoyer une réponse appropriée à travers l'écriture dans la réponse (response.getWriter().print()).

Ce code peut être testé sans le javascript en inscrivant directement une URL comme:

http://localhost:7654/ajaxSupprimer?id=pipo

Le cas pipo devrait donner une erreur. Ce type d'URL permet de tester facilement le code contrôleur sans avoir à effectuer un appel via Javascript.

AVERTISSEMENT: l'exemple fournit ne tient absolument pas compte des cas d'erreur.

Impacts sur l'approche MVC

En résumé, l'approche MVC que nous avons appliquée à notre application se décrit comme:

  1. une action de l'utilisateur est une URL avec des paramètres texte
  2. le contrôleur réagit à cette action en effectuant les traitements nécessaires, les accès à la BD etc.
  3. le contrôleur passe uniquement les objets nécessaires à la création de la vue.
Ce qui reste vrai : une action est toujours une url avec des paramètres; le contrôleur est responsable de la validation, des accès à la BD en réaction à une action.

Ce qui change : le résultat est un texte envoyé au navigateur, la vue initiale est modifiée par javascript. Le débogage de la vue ne peut plus se faire sur le code serveur Java, il faut travailler en javascript. 

Fichiers 

Vous trouverez l'exemple AJAX dans le projet ici.

Aucun commentaire:

Enregistrer un commentaire