Accueil > WebObjects > Applications Web : Gestion d’Etat

Applications Web : Gestion d’Etat

Par Apple Computer, Inc. © 2002 (Dernière mise à jour 3 Janvier 2002),

Traduit par Thierry, 19/03/2003.

Le web—de part sa nature—est un média sans état. Un serveur web reçoit une requête, produit une réponse et la retourne au navigateur web—sans aucune connaissance des requêtes précédentes du même utilisateur.

Une application web, cependant, a besoin de conserver l’état entre des requêtes du même utilisateur de manière à fournir une expérience acceptable pour l’utilisateur. Par exemple, de nombreux sites web vous permettent d’acquérir des articles en utilisant le modèle du caddie. De telles applications doivent se rappeler du contenu de votre caddie au fur et à mesure que vous naviguez sur le site. WebObjects encode un identifiant unique pour chaque requête. Cet indentifiant est utilisé pour conserver un état par dessus un média qui n’en a pas. Se reporter à “Traitement des Requêtes” pour plus d’informations.

Une partie de cet état se trouve dans la session. Bien que vous puissiez passer des informations dans un sens et dans l’autre entre des composants web, vous avez souvent besoin de maintenir l’état qui est partagé entre les composants. Plutôt que de passer cette information d’un composant à un autre (comme décrit dans “Communication entre Composants”), vous pouvez le stocker à un niveau plus élevé—dans l’objet Session. Chaque composant a accès à l’objet Session, les données qui sont stockées dans cet objet sont donc globalement accessibles.

Dans ce chapitre, vous allez :

  • stocker des informations persistentes dans l’objet Session,
  • accéder à la session à partir de plusieurs composants web,
  • voir les avantages de rendre réutilisable vos composants web.

La Session

Une session est une période de temps durant laquelle un utilisateur interagit avec votre application. Puisque toute application peut avoir plusieurs utilisateurs simultanément, elle peut avoir plusieurs objets Session. Chaque session a ses propres données et ses propres copies mises en cache des composants que l’utilisateur a requis, comme illustré dans la Figure 8-1.

Figure 8-1 Relation entre les objets application et session
[image: ../art/sessions.gif]

La session est représentée comme une instance de la classe Session (Session.java dans un projet d’application WebObjects). La classe Session est un extension de la classe WOSession (com.webobjects.appserver). Initiallement, la session n’a que des comportements fournis par WebObjects, mais vous pouvez ajouter des méthodes et des variables personnalisées. Par exemple, si vous construisez une application de shopping en ligne, la session serait un endroit approprié pour y stocker le caddie d’un utilisateur parce que la session est attachée à un utilisateur particulier et persiste tant que l’utilisateur se sert de l’application.

Lorsque qu’une requête est traitée, WebObjects active automatiquement l’objet Session associé à l’utilisateur qui est à l’origine de la requête comme décrit dans Traitement des Requêtes.

La classe WOComponent comprend une méthode qui permet d’accéder à la session en cours. Les classes Java des composants web étendent cette classe et WebObjects active automatiquement la session correcte lorsqu’une requête est traitée. L’appel de la méthode session à partir d’un composant web (ou dans un chemin d’accès à une clé) vous ouvre une session pour l’utilisateur en cours.

Afficher et Editer une Liste d’Objets

Commencer par créer un projet “SessionState”, en utilisant les composants Main et UserEdit du projet “ComponentCommunication” créé dans le chapitre Communication entre Composants. Autrement, vous pouvez copier le répertoire SessionState (projects/Managing_State/starter/SessionState) dans votre répertoire de travail et passer directement à la section “Les Classes NSArray et NSMutableArray”.

Pour créer le projet “SessionState” :

  1. Créez un projet application WebObjects et nommez le SessionState.
  2. Retirer le composant Main du projet :
    1. Sélectionnez le groupe Main situé sous Web Components.
    2. Pressez Commande-Effacement.
    3. Cliquez sur Delete References & Files dans le dialogue.
  3. Ajoutez le composant Main du répertoire du projet “ComponentCommunication” :
    1. Sélectionnez le groupe Web Components dans la liste Files.
    2. Choisissez Project > New Group et nommez le groupe Main. Assurez-vous que le nouveau groupe reste sélectionné.
    3. Choisissez Project > Add Files, sélectionnez les fichiers Main.api, Main.java et Main.wo et cliquez sur Add.

      [image: ../art/pbsesstaaddmain.gif]

    4. Dans le dialogue qui apparaît, cochez “Copy items into destination group’s folder”, sélectionnez “Create Folder References for any added folders” et la cible “Application Server” et cliquez sur Add.

      [image: ../art/pbsesstaaddmain2.gif]

Maintenant, ajoutez le composant UserEdit du projet “ComponentCommunication” au groupe des Web Components et la classe User au groupes des Classes.

Les Classes NSArray et NSMutableArray

Maintenant, éditez le composant Main pour qu’il montre une liste d’utilisateurs au lieu d’un seul. Pour cela, vous devez utiliser les classes NSArray et NSMutableArray.

La classe NSArray (com.webobjects.foundation) représente une collection ordonnée d’objets, comme la classe Java Array (java.lang). Les objets NSArray ne peuvent pas être changés une fois qu’ils sont instanciés. (Le tableau lui même n’est pas modifiable, mais les éléments qu’il contient peuvent l’être si leur type est sujet à mutation). La classe NSMutableArray (une sous-classe de NSArray) est à l’intention des tableaux qui nécessitent de croître et de rétrécir dynamiquement.

Les sections suivantes listent les méthodes de NSArray et de NSMutableArray que vous pourriez trouver utiles au moment de manipuler des tableaux.

NSArray

objectAtIndex(int)
Renvoie l’objet situé à l’index entier donné. Le premier objet d’un NSArray est situé à l’index 0. Les objets sont retournés sous forme d’instances de java.lang.Object. Vous aurez peut-être à faire un “cast” des objets sous une classe spécifique pour les utiliser.
count
Renvoie un entier indiquant le nombre d’objets contenus dans le NSArray.

NSMutableArray

addObject(Object)
Ajoute un anObject à la fin du tableau, incrémentant la taille du tableau de 1.
removeObjectAtIndex(int)
Retire du tableau l’objet indiqué par l’index, causant le rétrecissement du tableau.

En plus de ces méthodes, les classes NSArray et NSMutableArray ont d’autres méthodes que vous pourrez trouver utiles. Vous pouvez les examiner en utilisant votre Java Browser ou en consultant la documentation API WebObjects sur http://developer.apple.com/webobjects.

Ajout du NSMutableArray à la Session

Vous pouvez utiliser WebObjects Builder pour ajouter un tableau à la classe Session.

  1. Ouvrez Main.wo dans WebObjects Builder.
  2. Ajoutez la variable d’instance userList à la classe Session :
    1. Sélectionnez session dans la liste Main.
    2. Contrôle-cliquez sur la liste Session et choisissez “Add Key to Session” dans le menu qui apparaît.

      [image: ../art/wobmainaddarray.gif]

    3. Nommez la variable userList.
    4. Sélectionnez l’option “Mutable array of” puis User dans le menu pop-up.
    5. Sous “Generate source code for”, assurez-vous que seul “An instance variable” est sélectionné et cliquez sur Add.

      [image: ../art/wobuserlist.gif]

  3. Initialisez le nouveau tableau dans le constructeur de Session.Le NSMutableArray doit être instancié lorsque l’objet Session est créé. Il est vide quand l’application démarre ; là, vous ajoutez des méthodes pour ajouter des objets au tableau.

    Editez le constructeur de la classe Session en ajoutant les lignes numérotées du Listing 8-1 qui comprend les méthodes addToUserList et removeFromUserList.

    Listing 8-1 La classe Session du projet “SessionState”

    import com.webobjects.foundation.*;
      import com.webobjects.appserver.*;
      import com.webobjects.eocontrol.*;
    
      public class Session extends WOSession {
          /** @TypeInfo User */
          protected NSMutableArray userList;
    
          public Session() {
              super();
    
              userList = new NSMutableArray();		        //1
          }
    
          /**		                                        //2
           * Ajoute un objet User à <code>userList</code>.
           *
           * @param newUser   l'objet User à ajouter
           */
          public void addToUserList(User newUser) {		    //3
              userList.addObject(newUser);		            //4
          }		                                            //5
    
          /**
           * Retire un objet User de <code>userList</code>.
           *
           * @param aUser   l'objet User à retirer
           */
          public void removeFromUserList(User aUser) {		//6
              userList.removeObject(aUser);		            //7
          }		                                            //8
      }

Ajout du WORepetition à Main

Un élément WORepetition parcours chaque élément d’un NSArray en répétant une seule fois un ensemble de code HTML (incluant de manière possible des éléments WebObjects) pour chaque élément.

Un WORepetition comporte des liaisons pour la liste des éléments à parcourir (l’attribut list) et pour la variable à utiliser pour contenir temporairement chaque élément de la liste (l’attribut item). Au fur et à mesure que le contenu d’un WORepetition est affiché, l’élément en cours de la liste est stocké dans item. Les éléments WebObjects situés au sein du WORepetition peuvent faire référence à cette variable de remplacement, et les valeurs de chaque élément y est substituée tour à tour.

Maintenant, vous enveloppez les éléments dynamiques de Main.wo dans un WORepetition. Vous pouvez utiliser la variable d’instance user comme variable de remplacement du WORepetition. Après avoir effectué les étapes suivantes, Main.wo devrait ressembler à la Figure 8-2.

  1. Dans Main.wo, supprimez le premier élément WOConditional (celui qui contient le texte “Aucune donnée utilisateur n’a été saisie.”).
  2. Copiez le contenu interne du WOConditional restant vers le presse-papiers et supprimer le WOConditional.
  3. Collez le presse-papiers à la suite du WOHyperlink “Editer”.
  4. Ajoutez une action deleteUser qui renvoie null.
  5. Ajoutez un WOHyperlink pour supprimer des utilisateurs :
    1. Ajoutez un élément WOHyperlink après le second WOString.
    2. Saisissez Supprimer comme titre du WOHyperlink.
    3. Ajoutez un retour charriot après le WOHyperlink en pressant Majuscule-Retour.
    4. Reliez l’attribut action du WOHyperlink “Supprimer” à la méthode deleteUser.
  6. Enveloppez les éléments dynamiques de Main.wo dans un WORepetition.
    1. Sélectionnez tous les éléments de la page.
    2. Choisissez WebObjects > WORepetition ou cliquez sur le bouton “Ajoute un WORepetition” de la barre d’outils.
  7. Reliez l’attribut list du WORepetition à session.userList.Glisser-déposez à partir de session.userList vers le premier carré de WORepetition.
  8. Reliez l’attribut item du WORepetition à user.Glisser-déposez à partir de user vers le second carré de WORepetition.
  9. Ajoutez une action addUser qui renvoie une page UserEdit.
  10. Ajoutez un WOHyperlink pour ajouter de nouveaux utilisateurs.
    1. Ajoutez un WOHyperlink sous le WORepetition.
    2. Saisissez Ajouter un Utilisateur comme titre du WOHyperlink.
    3. Reliez l’attribut action du WOHyperlink à la méthode addUser.

Figure 8-2 Le composant Main avec un WORepetition
[image: ../art/wobmainworep.gif]

Mise à Jour des Utilisateurs

Vous pouvez utiliser le composant UserEdit pour éditer un utilisateur arbitraire. Pour faire ceci, vous utilisez la méthode editUser de Main.java. La méthode comporte une logique conditionnelle qui n’est pas requise dans cette application. Editez la méthode editUser de façon à ce qu’elle ressemble au Listing 8-2.

Listing 8-2 La méthode editUser de la classe Main

public UserEdit editUser() {
      UserEdit nextPage = (UserEdit)pageWithName("UserEdit");

      nextPage.setUser(user);
      return nextPage;
}

La méthode editUser crée une instance de UserEdit et appelle sa méthode setUser avec user comme argument. La variable user contient l’objet approprié parce que, lorsque l’utilisateur clique sur “Editer”, WebObjects stoke les éléments de session.userList, correspondant à la ligne sur laquelle le lien Editer est placé, dans la variable d’instance user. Souvenez-vous que l’attribut item du WORepetition est relié à user.

Le composant UserEdit nécessite un changement mineure. La méthode submitChanges de la classe UserEdit n’a plus besoin d’invoquer la méthode setUser de Main (les données utilisateur sont stockées au niveau de la session que la classe Main peut accéder au travers de l’objet session). Editez la méthode submitChanges de façon à ce qu’elle ressemble au Listing 8-3.

Listing 8-3 La méthode submitChanges de la classe UserEdit

public Main submitChanges() {
      Main nextPage = (Main)pageWithName("Main");

      return nextPage;
}

Ajout d’Utilisateurs

C’est ici que tout prend forme. Vous avez déjà les moyens d’éditer un utilisateur particulier (le composant UserEdit) ; une liste des utilisateurs, qui est vide au départ (session.userList) ; et un WORepetition qui affiche votre liste (dans le composant Main). Il ne vous reste plus qu’à ajouter une manière de construire la liste.

Vous devez modifier la méthode addUser de Main.java de façon à ce qu’elle crée un nouvel objet User, l’ajoute à la liste des utilisateurs de la session et la passe au composant UserEdit avant que la page ne soit envoyée au navigateur pour être modifiée. Editez addUser de façon à ce qu’elle corresponde au Listing 8-4 en ajoutant les lignes numérotées. Remarquez plus particulièrement le code qui récupère l’objet Session. La méthode addToUserList de cet objet est alors invoquée avec l’objet User nouvellement créé comme argument.

Listing 8-4 La méthode addUser de la classe Main

public UserEdit addUser() {
      UserEdit nextPage = (UserEdit)pageWithName("UserEdit");

      // Obtient la session de l'utilisateur en cours.		                        //1
      Session session = (Session)session();		                                    //2

      // Crée un nouvel objet User.		                                            //3
      User newUser = new User();		                                            //4

      // Ajoute <code>newUser</code> à la liste des utilisateurs de la session.		//5
      session.addToUserList(newUser);		                                        //6

      // Envoie <code>newUser</code> à la page UserEdit.		                    //7
      nextPage.setUser(newUser);		                                            //8

      return nextPage;
  }

Supression d’Utilisateurs

La dernière étape consiste à modifier la méthode deleteUser de Main.java de façon à ce qu’elle retire un utilisateur de la liste. La méthode est similaire à la méthode addUser décrite dans le paragraphe précédent. La seule différence est qu’au lieu de créer un nouvel objet User et d’invoquer la méthode addToUserList de Session, elle invoque seulement la méthode removeFromUserList de Session avec l’objet User placé dans la variable d’instance user (mise à jour par WebObjects lorsque l’utilisateur clique sur Supprimer).

Ajoutez les lignes numérotées du Listing 8-5 à la méthode deleteUser de Main.java.

Listing 8-5 La méthode deleteUser de la classe Main

public WOComponent deleteUser() {

      // Obtient la session de l'utilisateur en cours.		                  //1
      Session session = (Session)session();		                              //2

      // Retire <code>user</code> de la liste des utilisateurs de la session. //3
      session.removeFromUserList(user);		                                  //4

      return null;
  }

Lancer l’Application

Construisez et lancez l’application. Vérifiez que les utilisateurs que vous créez sont ajoutés à la liste et que vous pouvez modifier et supprimer des utilisateurs existants.

Figure 8-3 L’application SessionState en action
[image: ../art/websessta.gif]

Avantages de l’Encapsulation

Les avantages tirés du déplacement de la liste des utilisateurs vers la session sont tous organisationnels. Si vous ajoutez d’autres composants qui interagissent avec la liste des utilisateurs de l’application, ils peuvent partager la liste présente dans la session sans aucun changement de code supplémentaire.

Remarquez aussi que le composant UserEdit nécessite un changement minime parce que vous l’avez écrit pour qu’il fonctionne sur tout objet User donné sans établir de relations étroites avec d’autres parties de l’application. Puisque tous les composants web sont des objets, vous pouvez utiliser l’encapsulation, un avantage traditionnel de la programmation orientée objet.

Aller Plus Loin

Ce chapitre a présenté de nombreux nouveaux concepts. Ceux ci peuvent être combinés avec les techniques que vous avez déjà apprises pour ajouter plein de fonctionnalités. Voici quelques idées pour commencer :

  • Améliorer le lien “Editer” Donner à l’utilisateur la possibilité de modifier les utilisateurs du tableau en cliquant directement sur leur nom plutôt que sur le lien Editer. Vous pouvez faire ceci en remplaçant le texte statique du WOHyperlink par le WOString qui affiche le nom de l’utilisateur.
  • Indiquez si la saisie est complète Ajoutez une indication textuelle sur le fait que la saisie est complète en utilisant un WOConditional et la propriété entryIncomplete de la variable user.
  • Montrez le nombre d’éléments de la liste Utilisez un WOString et la méthode count de userList pour afficher le nombre de lignes dans la liste.

Textes originaux en anglais sur developer.apple.com : WebObjects Web Application - Managing State

Thierry WebObjects ,

  1. Pas encore de commentaire
  1. Pas encore de trackbacks
Vous devez être identifié pour poster un commentaire