dimanche 21 octobre 2012

Java Serveur App 6 : attributs de requête/session/contexte

Jusqu'ici, nous avons vu:
  • les pages JSP et leur balises
  • les motifs URL et les liens avec une Servlet contrôleur
  • les différents mode de redirection
Le problème est que nous n'avons pas de moyen de partager des objets Java entre différentes pages ou encore entre le contrôleur et une page. Nous allons voir ici comment mettre en place un tel partage.

Gestion des attributs

La requête HTTP (dans les pages ou dans la contrôleur) dispose de deux méthodes appelées setAttribute et getAttribute. Ces méthodes permettent de stocker ou de récupérer un objet dans dans la requête.

L'exemple classique est le suivant:
  1. Votre classe contrôleur veut passer un objet nommé panier de classe Panier à la vue JSP.
  2. Dans le code du contrôleur, vous effectuez l'instruction

    request.setAttribute("panier",panier);

  3. Dans le code de la page JSP, vous effectuez l'instruction

    Panier recupere = (Panier) request.getAttribute("panier");


Requête, session et contexte

Il existe plusieurs portées pour les attributs :

  • la requête HttpRequest permet de gérer des attributs, le cas le plus courant est une servlet qui passe un objet à une page JSP dans le cas d'une redirection via le requestDispatcher.
  • la session HttpSession permet de gérer des attributs pour l'ensemble d'une session, c'est à dire l'ensemble des pages de votre application pour un client.
  • le contexte ServletContext permet des attributs partagés pour toutes les sessions de  l'application.
Pour chaque objet que vous souhaitez partager via un attribut, il faut déterminer quelle sera 
  1. sa durée de vie: un attribut de contexte dure tant qu'on ne le supprime pas ou qu'on n'arrête pas le serveur. Un attribut de requête disparaît avec la requête.
  2. son utilisateur: si un élément est spécifique à un client, ce sera soit la requête soit la session. Sinon ce sera le contexte.
Exemple de la commande en session

Nous allons voir comment gérer un objet commande (similaire à un panier d'achats) dans notre session. Le code source de la classe Java modélisant une commande sera : 

package com.deguet;

import java.util.HashMap;
import java.util.Map;

public class CommandeEnSession {

 public Map<String, Integer> items;
 
 public CommandeEnSession(){
  items = new HashMap<String, Integer>();
 }
 
 public void addItem(String name){
  if (items.containsKey(name)) items.put(name, items.get(name)+1);
  else items.put(name, 1);
 }
 
 public int totalQuantity(){
  int result = 0;
  for (String name: items.keySet()) result += items.get(name);
  return result;
 }
 
 public int itemQuantity(){
  return items.size();
 }
 
 public String toString(){
  String result = "";
  for (String name: items.keySet())
   result += "("+name+" : "+items.get(name)+")";
  return result;
 }
}


Maintenant, pour ajouter des éléments à cette commande, l'action dans les vues devra ressembler à :


<a href="ajouterCommande?name=Pizza pour trois">Ajouter</a>

Cette action va déclencher le motif URL "ajouterCommande" avec comme paramètre le nom du plat. Il faut écrire le code contrôleur qui réagira à cette action:

if (action.equals("/ajouterCommande")){
 // récupération du paramètre de l'ajout, le plat à ajouter
 String plat = request.getParameter("name");
 System.out.println("Controler GET ajouter le plat "+plat);
 // si la commande n'existe pas dans la session, la créer
 CommandeEnSession commande = (CommandeEnSession) request.getSession().getAttribute("commande");
 if (commande == null) {
  commande = new CommandeEnSession();
  request.getSession().setAttribute("commande",commande);
 }
 // ajouter le plat
 commande.addItem(plat);
 System.out.println("La commande est  "+commande);
 // rediriger vers le menu
 response.sendRedirect("/menu");
 return;
}




Afin de vérifier que tout fonctionne correctement, nous allons maintenant voir comment afficher le panier dans la page commande.jsp:

<table class="table table-striped">
 <thead>
  <tr>
   <th>Plat</th>
   <th>Quantité</th>
  </tr>
 </thead>
 <tbody>
 <% 
 // si il existe une commande
 CommandeEnSession commande = (CommandeEnSession) session.getAttribute("commande");
 if (commande != null){
  for (String name : commande.items.keySet()){
   Integer qty = commande.items.get(name);
   %>
   <tr>
    <td><%=name %></td>
    <td><%=qty %></td> 
   </tr>
   <%
  }
 }
 %>       
 </tbody>
</table>


Nous avons vu comment créer un objet d'une classe Java, y ajouter des items et afficher son état dans une page JSP.




Fichier du restaurant avec commande gérée en session

Vous trouverez ici l'exemple du projet avec une gestion simple d'une commande en session. Vous trouverez également un widget dans l'entête JSPF permettant d'afficher l'état de la commande si il en existe une.

Aucun commentaire:

Enregistrer un commentaire