/>
id="update" value="Update" action="#{customerMBean.update}"/> juste après le menu déroulant pour les discountCodes... Vous comprenez maintenant ce que cela signifie :
Si on clique sur le premier bouton, on appelle list() dans CustomerMBean.java,
Si on clique sur le second bouton on appelle update()...
Regardons la version actuelle de la méthode update() :
view plainprint?
public String update() {
System.out.println("###UPDATE###");
customer = customerManager.update(customer);
return "CustomerList";
}
Cette méthode prend la propriété "customer", de type Customer et appelle une méthode métier dans le gestionnaire de clients qui va mettre à jour le client en base. Les attributs de cette propriété (nom, etc...) ont pour valeurs celles du formulaire de la page de détails. Si on a modifié ces valeurs avant de cliquer sur le bouton "update", les attributs de la propriété ont été modifiés. Donc on a bien dans "customer" un client mis à jour (en mémoire pour le moment, regardez ce que fait customerManager.update() pour voir. On verra en cours que c'est là que se fait la modification en base de données).
Il existe en effet une relation entre les clients et les codes de remise. Regardez attentivement la classe entité Customer.java, vous verrez que le code de remise est un attribut discountCode de type DiscountCode. Or le menu déroulant dans la page de détails, lorsqu'on modifie le code de remise, nous renvoie une String. C'est le travail du Converter de transformer cette string en objet de type DiscountCode !

Observez la requête nommée DiscountCode.findByDiscountCode définie dans un attribut de la classe bean entité DiscountCode. Cette requète possède un paramètre noté :discountCode. Quand on donne la valeur d'un code de réduction à ce paramètre, on peut récupérer l'objet de type DiscountCode correspondant. On propose d'utiliser une nouvelle méthode public DiscountCode getDiscountCodeByDiscountCode(char code) dans le bean session session.DiscountCodeManager. Voici cette méthode:
view plainprint?
public DiscountCode getDiscountCodeByDiscountCode(char code) {
Query query = em.createNamedQuery("DiscountCode.findByDiscountCode");
query.setParameter("discountCode", code);
return (DiscountCode) query.getSingleResult();
}
Observez: on associe le caractère code au paramètre de requête "discountCode", et on récupère un unique résultat de type DiscountCode: query.getSingleResult().
Voici finalement ce qu'on vous propose comme transformation String->DiscountCode par le Converter:
view plainprint?
private Converter discountCodeConverter = new Converter() {
@Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
char code = value.charAt(0);
DiscountCode dc = discountCodeManager.getDiscountCodeByDiscountCode(code);
return dc;
}
@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
DiscountCode dc = (DiscountCode) value;
return dc.getDiscountCode()+" : "+dc.getRate()+"%";
}
};
Exécutez, testez, amusez-vous à modifier les valeurs des clients, vérifiez dans le gestionnaire de base de données de netbeans que les modifications ont été prises en compte...
Problèmes devant encore être réglés :
Si on ouvre deux listes dans deux onglets différents, et qu'on modifie deux clients en même temps, que peut-il arriver ? Pourquoi ?
Les URLs ont tous un temps de retard, la page de détails affiche l'URL de la liste, etc. Pourquoi ? Nous verrons en cours comment corriger ce problème.
Ajoutez une trace dans la méthode getCustomers() de CustomerMBean.java, affichez la liste des clients, la méthode est appelée plusieurs fois. Proposez une optimisation. Attention, cela peut provoquer d'autres problèmes...
Correction de ce TP utilisant diverses améliorations vues en cours, et corrigeant la plupart des problèmes évoqués précédemment Cette correction fait diverses choses :
Elle "cache" la liste des customers qui doivent être affichés dans la table. Vous avez pu remarquer en mettant un println dans la fonction getCustomers() qu'elle était appelée plusieurs fois. Requêter dans cette méthode est non seulement peu performant (on va requêter plusieurs fois) mais comme l'ordre des éléments retournés peut changer, cela "casse" les fonctionalités de tri et de filtres de la datatable Primefaces.
Dans la page jsf CustomerList.xhtml on a rajouté un lien ou un bouton "refresh" qui appelle la méthode refresh... dans le backing bean, qui force ma mise à jour du modèle en faisant un appel à la bd.
Pour que le bouton "reload" du navigateur fasse la même chose, on a utilisé un "preRenderView" listener qui appelle cette même méthode refresh.
Dans le formulaire, on a mis des f:viewParam pour récupérer un paramètre http nommé id, passé dans l'url. Cette ligne de gestion des viewParam appelle la méthode setId() du backing bean. Ainsi, lorque la page est invoquée avec un paramètre ?id=1 on va initialiser une propriété/modèle de nom id et de valeur 1 dans le backing bean.
On a mis un preRenderViewListener dans la page du formulaire, qui appelle une méthode du backing bean pour qui va chercher le Customer qui a pour id la valeur initialisée dans l'étape précédente. On initialise donc le modèle utilisé par les champs du formulaire -> le formulaire sera pré-rempli lors du rendu !
Du coup on a un formulaire autonome !!!! On peut copier/coller son URL et l'envoyer par mail, le lien affichera toujours un formulaire pré-rempli
On a mis ?faces-redirect=true partout où on fait de la navigation -> ceci force le mode de navigation Post-Redirect-Get (PRG) ce qui permet d'avoir toujours les bons URLs affichés, ceux correspondant à la page affichée.
On a modifié les boutons dans la première colonne pour que ce soient juste des liens statiques, et non des liens ou boutons appelant des méthodes de controle dans le backing bean.
J'ai aussi simplifié la manière dont on affiche la liste en utilisant une méthode similaire aux datatables, avec un attribut var=... regardez donc la partie selectItems et la methode getAllDiscountCodes dans le backing bean.
Pour la semaine prochaine:
Inspirez-vous de l'article d'introduction à JSF 2.0 du site de Netbeans http://netbeans.org/kb/docs/web/jsf20-intro.html (Cet article contient plein de trucs pour développer plus rapidement et plus efficacement sur NetBeans !!!) pour utiliser une facelet pour rendre le site ergonomique (un en-tête avec le titre du TP (statique) et le titre de chaque page mis en forme, et une colonne de gauche qu'on utilisera plus-tard pour mettre les liens de navigation).
Mots clés:
Attacher fichier ou image
Fichiers (2) Images (39)
« précédent suivant »
Voir 1 - 6 sur 39 images | Voir tout
Haut du formulaire Bas du formulaire

Aucune description
Snap3.jpg Actions

Aucune description Snap28 (2... Actions

Aucune description
Snap23.jpg Actions

Aucune description Snap40.jpg Actions

Aucune description Snap39.jpg Actions

Aucune description Snap38.jpg Actions |