Vous n'êtes pas connecté. Connexion
|
|
Client HTML5 Web Service RESTFullDe $1Dans 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 Michel Buffa cette année. 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. KnockoutKnokcout 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.
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: "http://localhost:8080/Bibliotheque/webresources/categorie", 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)); }); });
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 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 palier ce problème est de modifier les paramètres du serveur pour accepter les requête asynchrones tout autre ou pour certains domaines en fonction des besoins de l'application; Dans notre cas, nous allons modifier la configuration de notre application RESTFull pour acceter des requetes de n'importe quel domaine.
@WebFilter(filterName="Test",urlPatterns={"/webresources/*"}) public class Test implements javax.servlet.Filter{ @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.out.println("doFilter"); HttpServletResponse res = (HttpServletResponse) response; //Dire qu'on accepte des requetes de n'importe quel domaine sur les ressources gérés par la servlet res.addHeader("Access-Control-Allow-Origin", "*"); chain.doFilter(request, response); } @Override public void init(FilterConfig filterConfig) throws ServletException { System.out.println("Init"); //throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } @Override public void destroy() { System.out.println("destroy"); // throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } } Nous allons maintenant utiliser knockout pour afficher la réponse dans un tableau
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. var Category = function(categorie) { this.id = ko.observable(categorie.id); this.nom = ko.observable(categorie.nom); this.description = ko.observable(categorie.description); };
Note: Le modèle ici représente la logique applicative de la vue (liste des categories, ajouter/editer/supprimer categorie etc....) 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);})); };
<h2>Categories</h2> <div class='categorielist'> <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> <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)
$(function() { $.ajax({ url: "http://localhost:8080/Bibliotheque/webresources/categorie", type: "GET", headers: { Accept: "application/json" } }) .success(function(data, status, jq) { ko.applyBindings(new ViewModel(data)); }) .error(function(jq, status, error) { $(".error").text(JSON.stringify(status + " " + error)); }); });
<style> body { font-family: arial; font-size: 14px; } .categorielist { padding: 1em; background-color: #EEEEDD; border: 1px solid #CCC; max-width: 655px; } .categorielist input { font-family: Arial; } .categorielist b { font-weight: bold; } .categorielist p { margin-top: 0.9em; margin-bottom: 0.9em; } .categorielist select[multiple] { width: 100%; height: 8em; } .categorielist h2 { margin-top: 0.4em; font-weight: bold; font-size: 1.2em; } .error { color: red; } .categorielist TR { vertical-align: top; } .categorielist TABLE, .categorielist TD, .categorielist TH { padding: 0.2em; border-width: 1px; margin: 0; } .categorielist TD A { font-size: 0.8em; text-decoration: none; } .categorielist table.contactsEditor > tbody > TR { border-bottom: 1px solid silver; } .categorielist td input { width: 8em; } </style> Jouons un peu avec knockout!
<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>
<input data-bind='value: description, enable: (parseInt(id())%2 ===0)' /> Voyez ce qui se passe quand vous faites des modifications sur la vue!
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: "http://localhost:8080/Bibliotheque/webresources/categorie/" + categorie.id(), 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! TP à rendre (Vendredi 8 novembre 2013)Finalisez l'application en y ajoutant les options suivantes:
Modalités
|
Powered by MindTouch Deki Open Source Edition v.8.08 |