Les technologies XML Cours X : Approche RESTFull Février 2016 - Version 1.0 - 1 Approche RESTFull Jusqu’à maintenant nous avons principalement travaillé avec une approche Application et/ou Service. L’intégration se faisait ensuite sur la base d’un écran (ou partie d’écran) pour un service. Avec l’avènement de HTML et de l’approche REST la tendance est maintenant plutôt aux approche SPA (Single Page Application). L’idée sous-jacente est que plutôt que de télécharger l’ensemble des éléments nécessaires à l’application (Données, code, UI) seules les données soient rapatriées selon les action de l’utilisateur. 2 Approche RESTFull - SPA Une application web monopage (en anglais single-page application ou SPA) est une application web accessible via une page web unique. Le but est d'éviter le chargement d'une nouvelle page à chaque action demandée, et de fluidifier ainsi l'expérience utilisateur. Deux méthodes existent pour ce faire : soit on charge l'ensemble des éléments de l'application (contenu, images, CSS et JavaScript) dans un unique fichier HTML, soit on récupère et affiche dynamiquement les ressources nécessaires en fonction des actions de l'utilisateur. Source Wikipedia 3 Approche RESTFull - SPA Ce type d’application Web permet une meilleure expérience utilisateur en se rapprochant terme de performance des application desktop. D’ailleurs ce type de développement en conjonction de l’approche RWD (Responsive Web Design) permet de réaliser en une seule fois : Un site Web Une application Tablette Une application Mobile 4 Approche RESTFull - RWD Un site web adaptatif (anglais RWD pour responsive web design, conception de sites web adaptatifs selon l'OQLF1) est un site web dont la conception vise, à offrir une expérience de consultation confortable même pour des supports différents. L'utilisateur peut ainsi consulter le même site web à travers une large gamme d'appareils (moniteurs d'ordinateur, smartphones, tablettes, TV, etc.) avec le même confort visuel et sans avoir recours au défilement horizontal ou au zoom avant/arrière sur les appareils tactiles notamment, manipulations qui peuvent parfois dégrader l'expérience utilisateur, tant en lecture qu'en navigation. 5 Source Wikipedia Approche RESTFull - RWD La notion de « web adaptatif » repense la manière de concevoir les parcours de navigation applicatif : il ne s’agit plus d’optimiser les « parcours » par terminaux mais au contraire de concevoir une seule interface auto-adaptable. Le RWD utilise les concepts techniques suivants: • Media Queries CSS 3 • Grille Fluide • Gestion relative des images. 6 Approche RESTFull - RWD Media Queries CSS 3 Cette nouveauté CSS 3 consiste à appliquer des règles différentes selon les caractéristiques du terminal sur lequel afficher l’élément. Ce sont des extensions de la règle CSS 3 @media Dans la pratique on défini généralement un « point de rupture » à partir duquel l’affichage doit être « adapté ». 7 Approche RESTFull - RWD La Grille Fluide Ce concept repose sur le dimensionnement relatif des éléments d’une UI les uns par rapport aux autres. Gestion relative des images Les images ayant un besoin de flexibilité sont également redimensionnées en unité relative, afin de prévenir un éventuel débordement du contenu en dehors de son élément conteneur. 8 Approche RESTFull – RWD Comme souvent il existe deux « approches » différentes pour implémenter ces concepts. Le « responsive degradation » qui consiste à « appauvrir » l’interface selon les terminaux en simplifiant l’ergonomie. L’approche « mobile first » qui consiste à développer une application en prenant en compte un déploiement mobile. Cette approche tend à rapprocher l’expérience utilisateur sur l’ensemble des terminaux. 9 Approche RESTFull Même si l’approche RESTFull peut être utilisée dans des applications Web « classique » elle prend tout son sens en conjonction d’une interface Homme-Machine respectant les paradigmes RWD et SPA. Ainsi elle permet de réaliser des applications respectant les dernières tendances ergonomiques et s’adaptant facilement à l’évolution des terminaux numériques. 10 REST et JAX-RS Même si REST n'est pas une norme mais un ensemble de standard, il existe une norme Java pour développer des WebServices en Java. Cette norme s'appelle JAX-RS (The Java API for RESTful Web Services JSR 311). JAX-RS utilise des annotations pour que des classes java répondent aux paradigmes REST. Jersey est l'implémentation de référence de cette JSR. Elle permet d'exécuter des WS RestFul dans un conteneur de Servlet. La bibliothèque fournie également les éléments pour implémenter des classes clientes 11 REST et JAX-RS Nativement JAX-RS supporte les représentation XML et JSON à travers l'API JAXB. Par conséquent, il suffit de définir le type de représentation d’une méthode en JSON pour que JAXB automatiquement génère une représentation de ce type. Il est donc nécessaire de « coder » les représentations autres que JSON et XML que l'on souhaitent avoir pour ces ressources. 12 Annotations JSR 311 Annotations Description @PATH(your_path) Précise le PATH de la ressource utilisée pour définir l'URL @POST Indique la méthode répond à la méthode HTTP POST @GET Indique la méthode répond à la méthode HTTP GET @PUT Indique la méthode répond à la méthode HTTP PUT @DELETE Indique la méthode répond à la méthode HTTP DELETE @Produces(MediaType.TEXT_PL Indique les types MIME qui peuvent AIN[, more-types]) être fournie par la méthode @GET @Consumes(type[, more-types]) Précise le type MIME en entrée de la méthode 13 Annotations JSR 311 Annotations Description @FormParam Utilisé pour définir un paramètre d’un formulaire en paramètre de la méthode @Provider Utilisé pour spécifier le « producteur » d’une représentation. Peut aussi permettre de gérer les erreurs en transformant une exception en erreur http. @PathParam Utilisé pour définit un paramètre de l'URL en paramètre de la méthode 14 JAX-RS mise en œuvre de Jersey Par défaut les moteurs de servlet n’implémentent pas la JSR 311. Pour que votre application puissent « héberger » des « ressources », il suffit d’ajouter dans le WEB-INF/lib de celle-ci les bibliothèques suivantes : 15 JAX-RS: mise en œuvre de Jersey Puis dans le fichier web.xml de votre application ajouter la déclaration suivante : <servlet> <servlet-name>Jersey</servlet-name> <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class> <init-param> <param-name>com.sun.jersey.config.property.packages</param-name> <param-value>package contenant vos ressources</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>Jersey</servlet-name> <url-pattern>/rest/*</url-pattern> </servlet-mapping> 16 JAX-RS: Création d’une ressource @Path("/Contact") public class Contact { @POST @Produces(MediaType.TEXT_PLAIN) public String ajouteContact(@FormParam("nom") String nom,@FormParam("prenom") String prenom,@FormParam("telephone") String telephone) { Personne p = new Personne(); p.setNom(nom); p.setPrenom(prenom); p.setTelephone(telephone); ArrayList<Personne> aL = (ArrayList<Personne>)ListeDePersonne.getlPersonne(); aL.add(p); return « Contact ajouté"; } 17 JAX-RS: Récupération d’une Ressource de type Liste @GET @Produces(MediaType.APPLICATION_JSON) public List<Personne> getListeAsJsonArray() { return ListeDePersonne.getlPersonne(); } 18 JAX-RS: Structure de données package models; import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement public class Personne { private String nom; private String prenom; private String telephone; La sérialisation JSON est effectué par JAXB à travers l’annotation @XMLRootElement public Personne() { super(); // TODO Auto-generated constructor stub } <element javabeans> } 19 JAX-RS: Récupération d’un élément d’une liste @Path("Contacts/{contactid}/") @Produces(MediaType.APPLICATION_JSON) @GET public Personne getPersonne(@PathParam("contactid") String contactid) throws Exception{ Personne p = ListeDePersonne.getlPersonne().get(Integer.parseInt(contactid)); if (p == null) throw new Exception("Personne, " + contactid + ", non trouvée"); return p; } 20 Récupération d’une personne en Javascript <script type="text/javascript"> function affPersonne() { var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function () { if (xhr.readyState == 4 && xhr.status == 200 ) { Personne = JSON.parse(xhr.responseText); document.write("Nom: "+Personne.nom+"<br/>") document.write("Prenom: "+Personne.prenom+"<br/>") document.write("Telephone: "+Personne.telephone+"<br/>") } } xhr.open("GET","http://localhost:9080/testJAXRS/rest/Liste/Contacts/1",true); xhr.send(); } affPersonne(); </script> 21