Amosse EDOUARD > Consumer les web services RESTFull en JAVA > Client HTML5 Web Service RESTFull

Client HTML5 Web Service RESTFull

De $1

Dans cette section du TP, nous allons créer un client HTML5 qui consumera le web service du TP1.  Ce TP se basera fortement sur le cours HTML5 que vous avez eu avec précédemment.  Nous utiliserons aussi  knockout, une bibliotheque JavaScript  qui nous permettra de faire du MVVM (Model Vue Vue Model) en utilisant que du JavaScript et les métadonnées MTML5.

Knockout

Knokcout  est une librairie Javascript Open Source permettant de faire du MVVM (Model Vue Vue Model). Le pattern MVVM permet une communication bidirectionnel entre le model et la vue sans passer par un contrôler ; Il est particulièrement intéressant pour les vues dynamiques. L’idée est d’associer les contrôles d’une vue avec des attributs d’un modèle de telle sorte que les modifications de l’un soient automatiquement prises en compte par l’autre.

Afin de vous aider à mieux comprendre le principe des services web, nous allons créer une autre application web complètement séparée de l'application Web exposant le Web Service. 

  • Créez un projet HTML5/JavaScript sur Netbeans (File à New Project à HTML5 javaScript è Next)

  html5-screen_1.png

  •  Dans la fenêtre suivante, nommez votre projet puis Next  

 html5-screen_2.png

  • Sur la prochaine interface, choisissez l’option Download Online Templates è Twitter Bootstrap è Next

    html5-screen_3.png 
  • Dans l’écran qui suit, sélectionnez Jquery et Knockout en appuyant à chaque fois sur > pour les faire passer du panel de gauche vers celui de droite è Finish

    html5-screen_4.png
  • A ce niveau vous devez avoir un projet qui ressemble à ceci

    html5-screen_5.png  
  • Ajoutez une nouvelle page html au projet (Faites bouton droit sur le projet è  New è  HTML File)
  • Ajoutez les références jquery et knockout à la page que vous venez de créer  

N.B : Avec Jquery, on peut lancer déclencher automatiquement une action au chargement de la page, indépendemment de l'action utilisateur. Nous allons utiliser cette option pour lancer une requête AJAX au service Web.

$(function() {
                $.ajax({
                    url: [URI vers la liste des catégories],
                    type : "GET",
                    headers: {
                        Accept: "application/json"
                    }
                })
                        .success(function(data, status, jq) {
                    $("div").text(JSON.stringify(data));
                })
                        .error(function(jq, status, error) {
                    $("div").text(JSON.stringify(status + " " + error));
                    
                });

            });
  •  Exécutez le projet (Faites bouton droit sur le projet puis Run)

Normalement, la requête ne doit pas aboutir! Elle est due au fait que votre application web et l'application RESTFull sont sous des domaines différents (localhost:8080 et localhost:8383).  C'est un mécanisme de sécurité sur les serveurs applicables par rapport aux requetes AJAX.  Elle est liée au Cross domain du serveur qui filtre les requetes AJAX en provenance d'un autre domaine. L'une des façons de résoudre ce problème est de modifier les paramètres du serveur pour accepter les requête en provenance d'autres domaines.  Pour ça, on va ajouter une nouvelle classe à notre application qui va s'occuper de la gestion des autorisations des requetes en provenance d'autres domaines. 

  1. Faites bouton droit sur le package contenant la classe ApplicationConfig.java --> New --> Other
  2. Selectionnez l'onglet Web Services dans l'ecran qui s'affiche 
  3. Choisissez Cross-Origine Resource Sharing Filter 
  4. Donnez un nom à la nouvelle classe, puis OK
  5. Votre classe doit ressembler à ceci 
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.netbeans.rest.application.config;

import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;
import javax.ws.rs.ext.Provider;

/**
 *
 * @author aedouard
 */
@Provider
public class RequestFilter implements ContainerResponseFilter {

    @Override
    public void filter(ContainerRequestContext requestContext, ContainerResponseContext response) {
        response.getHeaders().putSingle("Access-Control-Allow-Origin", "*");
        response.getHeaders().putSingle("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
        response.getHeaders().putSingle("Access-Control-Allow-Headers", "content-type");
    }
    
}

Attendez que le web service se redeploie puis retestez! Normalement la réponse du webservice devrait s'afficher, si ce n'est pas le cas jette un petit coup d'oeil dans la console developper du navigateur pour voir ce qui ne va pas. 

Nous allons maintenant utiliser knockout pour afficher la réponse dans un tableau

  • Créer un modèle pour représenter la/les ressources utilisées dans la vue  

Note : knockout propose la méthode observable, qui permet de s'abonner aux modifications qui pourront s'effectuer sur un objet. Dire qu'un objet est observable signifie que tout changement effectué sur l'objet est pris en compte par la vue associée et reciproquement.

Créez un nouveau fichier javascript (categorie.js) et ajoutez une référence dans la page html que vous avew créé précedemment.

/*
Ceci est equivalent à une classe Java, on veut faire propre!
*/  
var Category = function(categorie) {
                this.id = ko.observable(categorie.id);
                this.nom = ko.observable(categorie.nom);
                this.description = ko.observable(categorie.description);
            };
  • Créez un modèle pour la vue (Ajoutez la fonction qui suit dans le fichier categorie.js que vous venez de créer)

Note: Le modèle ici représente la logique applicative de la vue (liste des categories, ajouter/editer/supprimer categorie etc....)

/*
Cette function est le controlleur de la vue 
Elle assure la communication entre la vue et le modèle, une sorte de pont quoi! 
*/    
              var ViewModel = function(categories) {
                var self = this;
		//représente la liste des catégories
		//La fonction prend la réponse obtenue du serveur en paramètre
		//Ici nous supposons que vous avez chargé la liste des catégories
		//ko.utils.arrayMap itère sur la collection et pour chaque objet trouvé, elle crée une instance de categorie 
                self.categories = ko.observableArray(ko.utils.arrayMap(categories, function(categorie) { return new Category(categorie);}));
                };
  • Créons une table html pour afficher la liste des catégories! Remplacez la balise div par le contenu suivant :

On va utiliser le databinding de knockout pour remplir la table avec les données récupérées du WS.  On veut pour chaque objet obtenu afficher une ligne de la table et dans chaque colonne on afichera les attributs de l'objet catégorie récupéré.  Pour cela , on fera appelle à la fonction foreach sur la liste des catégories obtenues.  Dans chaque colonne de chaque ligne, nous ajouterons un label pour afficher la valeur des attributs de l'objet courant.  knockout utilise la propriété data-bind pour accéder aux propriétés des balises html; pour afficher un text dans un label, il suffit de faire appel à la propriété text. 

<h2>Categories</h2>
        <div >
            <table>
                <tr>
                    <th>Id</th>
                    <th>Nom</th>
                    <th>déscription</th>
                </tr>
                <tbody data-bind="foreach: categories">
                    <tr>
                        <td>
                            <label data-bind='text: id' ></label>
                        </td>
                         <td>
                            <label data-bind='text: nom' ></label>
                        </td>
                         <td>
                            <label data-bind='text: description' ></label>
                        </td>
                    </tr>
                </tbody>
            </table>
        </div>
        <div class="error"></div>

Note : Dans ce code, nous avons ajouté un table à trois colonnes (Id, Nom, Description)
Observez bien le contenu de la balise tbody, avez vous remarqué l'attribut "data-bind", knockout l'utilise pour faire du databinding sur les composants d'une vue. la fonction foreach permet d'itérer sur l'attribut categories du modèle de la vue. Pour chaque objet catégorie trouvé, une ligne sera ajouté dans la table avec en colonne les valeurs des attributs de l'objet courant.

  • On va déplacer le code ajax de texte qu'on avait mis dans la page html vers le fichier categorie.js, on le modifiera un tout petit pour créer une nouvelle fonction qu'on appelera getData.
  •  
var getData = function() {
    $.ajax({
        url: "http://localhost:8080/bibliotheque_ntdp/webresources/category",
                type: "GET",
        headers: {
            Accept: "application/json"
        }
    }).success(function(data, status, jq) {
//Cette fonction indique à knockout d'appliquer les données aux éléments de la page 
//Elle est toujours appelée quand les données sont pretes et est appelée qu'une fois 
        ko.applyBindings(new ViewModel(data));
    }).error(function(jq, status, error) {
        $(".error").text(JSON.stringify(status + " " + error));

    });
};

Maintenant que tout est pret, il nous suffit d'appeler la méthode getData pour charger les données du WS et remplir la page! Je vous fais confiance pour le faire tout seul cette fois!  

  • Testez la page! Normalement vous devriez avoir quelque chose comme ça : 

result8html5_1.png

  • Elle est moche votre page, vous etes d'accord! Ajoutons un peu de style pour que ca soit un tout petit peu plus agréable à voir. 
  • Vous vous rappelez du template bootstrap qu'on a intégré à la création du projet, il est temps de nous en servir.  Ajoutez la classe table table-striped à la balise table du html

Jouons un peu avec knockout!

  • A la place d'un label dans les champs du tableeu, mettez un input
<table class='contactsEditor'>
                <tr>
                    <th>Id</th>
                    <th>Nom</th>
                    <th>déscription</th>
                </tr>
                <tbody data-bind="foreach: categories">
                    <tr>
                        <td>
                            <label data-bind='text: id' > </label>
                        </td>
                        <td>
                            <input data-bind='value: nom' />
                        </td>
                         <td >
                            <input data-bind='value: description' />
                        </td>
                    </tr>
                </tbody>
            </table>
  • Testez maintenant!

result8html5_2.png

  • Inventons cette règle pour le fun! Nous autoriserons l'édition d'une ligne uniquement si l'id est pair!
<input data-bind='value: description, enable: (parseInt(id())%2 ===0)' />

result8html5_3.png

Voyez ce qui se passe quand vous faites des modifications sur la vue!
  • Ajoutez une nouvelle colonne action dans la table, afin d'ajouter des composantes pour effectuer des actions sur le modèle.
  • Pour chaque ligne du tableau ajoutez un bouton suppression et un bouton mise à jour!
  • Ajoutez deux nouvelles fonctions pour la suppression et la mise à jour d'une catégorie

Note : La suppression se fait dans la liste des contacts

A ajouter dans la vue

<input type="button" value="Supprimer" />

A ajouter dans le modèle

self.remove = function(categorie){
                   self.categories.remove(categorie);
                    $.ajax({
                        url: [URI],
                        type: "DELETE",
                        contentType: "application/json",
                        headers: {
                        Accept : "application/json"
                    }
                    })
                            .success(function(data, status, jq) {
                        // alert(status);
                        self.categories.remove(categorie);
                    })
                            .error(function(jq, status, error) {
                        $(".error").text(JSON.stringify(status + " " + error));

                    });
                };
                self.update = function(categorie){ 
                   //Effectuez votre requête AJAX ici
                };

 Testez! 

html5-screen_7.png

  • Ajoutez un bouton / une image qui permettra de créer une nouvelle categorie! L'action du bouton/image doit ajouter une nouvelle ligne dans la table avec des champs vides. Quand vous appuyez sur le bouton valider, appelez le WS pour créer une nouvelle catégorie.
  • Ajoutez un champ de recherche et un bouton permettant de filtrer les catégories de la table. Quand on clique sur le bouton effectuer une recherche Ajax vers le Web service afin de récupérer toutes les catégories dont le titre et/ou la description contient le text du champ de recherche. 
  • Répétez ces étapes pour la ressource livre du web service.  Quand on selectionne une catégorie dans la liste des catégories, afficher tous les livres de cette catégorie. 

 

 

Mots clés:
 
Images (6)
Voir 1 - 6 sur 6 images | Voir tout
Aucune description
result8ht...  Actions
Aucune description
html5-scr...  Actions
Aucune description
html5-scr...  Actions
Aucune description
html5-scr...  Actions
Aucune description
html5-scr...  Actions
Aucune description
html5-scr...  Actions
Commentaires (0)
Vous devez être connecté pour poster un commentaire.