Cloud PAAS: Google App Engine et Service JAX-RS
Dans cette application, vous apprendrez à créer un service REST à l'aide de l'implémentation de
référence JAX-RS (Jersey) et à le déployer sur Google AppEngine.
Conditions préalables
Pour ce tutoriel vous aurez besoin de :
• un compte Google AppEngine
• Eclipse Galileo (3.5.x)
• SDK Google App Engine pour Java
o Installez le plugin Google pour Eclipse comme documenté :
http://code.google.com/eclipse/docs/install-eclipse-3.5.html
o il est également utile d'avoir la documentation AppEngine et installer SDK google
cloud :
https://dl.google.com/dl/cloudsdk/channels/rapid/GoogleCloudSDKInstaller.exe
• bibliotheque référence JAX-RS, assurez-vous de prendre la version Jersey
1.1.5. Décompressez le fichier dans un répertoire que nous appellerons $JERSEY_HOME
• bibliotheque JAXB 2.2 pour simplifier le marshalling/unmarshalling du XML, et également
faciliter le support JSON. Le répertoire d'installation (jars) de JAXB s'appellera $JAXB_HOME
Création d'une nouvelle application
Pour créer un projet App Engine dans Eclipse :
1. Cliquez sur le bouton "Nouveau projet d'application Web" dans la barre d'outils. Il est
aussi possible de le faire en utilisant le menu File > Web Application Project
2. L'assistant "Créer un projet d'application Web" s'ouvre :
• Nom du projet : EmployeeService
• Forfait : com.ensem.employee.service
• Décochez "Utiliser Google Web Toolkit"
• Vérifiez que la version du SDK que vous utilisez est "App Engine 1.3.0" ; sinon configurez le
projet pour l'utiliser.
• Cliquez sur Terminer
Lancer l'application
Le SDK App Egine, installé avec le plugin Eclipse contient un serveur Web (basé sur Jetty), qui pourrait
être utilisé pour les tests et le débogage. Pour tester que votre application a été créée correctement,
sélectionnez le menu Exécuter > Exécuter en tant que > Application Web. Personnellement, je lance la
plupart du temps mon serveur en utilisant la commande de débogage Run > DebugAs > Web
Application. En mode débogage, vous pouvez modifier le code source et tester sans redémarrer le
serveur.
Le serveur web démarre automatiquement, vous devriez voir le message suivant dans la console
Eclipse
Le serveur s'exécute sur http://localhost:8080/
Vous pouvez accéder à l'application et à l'exemple de servlet créé à l'aide de l'URL :
http://localhost:8080/employeeservice
Pour arrêter le serveur, cliquez sur le bouton Terminer dans la console Eclipse.
Configuration du support REST dans l'application
Pour pouvoir créer et exécuter des services REST dans votre application, vous devez :
• Ajoutez les JAX-RS, JAXB Jars dans votre projet et votre application
• Configurer l'application Web (web.xml) pour gérer les requêtes REST
Ajouter JAX-RS, JAXB à votre projet
1. Faites un clic droit sur le projet et sélectionnez l'entrée de menu Build Path > Configure
Build Path…
2. Cliquez sur le bouton Ajouter des JAR externes
3. Sélectionnez tous les fichiers JAR situés dans les dossiers $JERSEY_HOME/lib et
$JAXB_HOME/lib. Vous pouvez pour une meilleure visibilité et réutilisation créer une
bibliothèque utilisateur avec tous ces JARs
4. Vous devez également copier les JAR dans le répertoire web-inf/lib de votre application.
Cette étape est obligatoire pour vous assurer que les JAR sont inclus dans l'application
lorsqu'elle est déployée sur App Engine.
Configurer l'application Web
Dans cette étape, vous enregistrerez un nouvel URI pour gérer les requêtes REST. Pour ce faire, vous
devez enregistrer un nouveau servlet qui utilise l'API Jersey et le configurer sur un URI spécifique (par
exemple : /ressources et/ou /rest) et configurer quels sont les packages Java contenant les classes
d'implémentation REST.
Ce service servlet qui répondra aux URL /resources/ et /rest/. Le paramètre de configuration de Jax-RS
pour répertorier les packages où se trouvent l'implémentation des services REST. Notez que vous
pouvez mettre autant de packages que nécessaire, il vous suffit de séparer les noms des packages.
par un ;
Création d'un service REST simple pour tester l'environnement
Le projet est maintenant prêt à contenir le service REST. Il est temps d'en créer un.Créez par exemple
la classe com.ensem.employee.service.rest.impl.HelloWorldResource, veillez à utiliser le nom du
package que vous avez configuré dans le web.xml pour la servlet Jersey, basé sur le configuration que
nous avons faite à l'étape précédente, le package est com.ensem.employee.service.rest.impl
Voici un exemple de classe avec les annotations JAX-RS :
01package com.ensem.employee.service.rest.impl;
02import javax.ws.rs.Path;
03import javax.ws.rs.GET;
04import javax.ws.rs.Produces;
05@Path("/hr/")
06public class EmployeeResource {
07
08 @GET
09 @Produces("text/plain")
dix @Path("/employee")
11 public String getEmployee() {
12 return "Hello World!";
13 }
14}
Vous devriez pouvoir le tester, arrêter le serveur et le relancer, entrez l'URL suivante dans votre
navigateur :
http://localhost:8080/resources/hr/employee
ou
http://localhost:8080/rest/hr/ employé
Déploiement de l'application sur Google App Engine
Avant de déployer l'application, vous devez enregistrer une nouvelle application dans Google App
Engine à l'aide de la console d'administration, voir la documentation :
http://code.google.com/appengine/docs/theadminconsole.html
Dans cet exemple, "ENSEM" est utilisé comme identifiant d'application.
Vous pouvez maintenant déployer facilement l'application sur Google App Engine en cliquant sur le
bouton "Déployer le projet App Engine" disponible dans la barre d'outils Eclipse.
Pour pouvoir déployer votre application sur Google App Engine, vous devez vérifier que votre
application peut être enregistrée, l'ID de l'application est stocké dans le WEB-INF/lib/appengine-
web.xml.
1<?xml version="1.0" encoding="utf-8"?>
2<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
3 <application>[your-application-id]</application>
4 <version>1</version>
5 <!-- Configure java.util.logging -->
6 <system-properties>
7 <property name="java.util.logging.config.file" value="WEB-INF/logging.properties"/>
8 </system-properties>
9</appengine-web-app>
Le bouton de déploiement d'App Engine vous demande plusieurs informations : nom d'utilisateur
(votre compte Google) et mot de passe.
Une fois le déploiement terminé, vous pouvez accéder à votre application à l'aide de l'URL suivante :
http://[your-application-id].appspot.com/resources/hr/employee
ou
http://[your-application-id].appspot .com/rest/hr/employee
Ajout du support XML et JSON au service
Ajoutons maintenant une nouvelle méthode pour manipuler un objet "Employé" à l'aide du service, et
le format de données doit être basé sur JSON et XML. C'est là que JAXB est utile, puisqu'il permet de
transformer facilement des objets Java marshall/unmarshall en XML -évidemment- et JSON
Création d'une classe d'employés
Commencez par la création d'une nouvelle classe pour manipuler les données Employee, il s'agit d'une
classe Java très simple qui pourrait ressembler au code suivant :
01package com.ensem.employee.service.model;
02import java.util.Date;
03
04public class Employee {
05 private String firstName;
06 private String lastName;
07 private Date hireDate;
08 private String email;
09 public Employee(String firstName, String lastName, Date hireDate, String email) {
dix this.firstName = firstName;
11 this.lastName = lastName;
12 this.hireDate = hireDate;
13 this.email = email;
14 }
15 public Employee() {}
16 public String getFirstName() {
17 return firstName;
18 }
19 public void setFirstName(String firstName) {
20 this.firstName = firstName;
21 }
22 public String getLastName() {
23 return lastName;
24 }
25 public void setLastName(String lastName) {
26 this.lastName = lastName;
27 }
28 public Date getHireDate() {
29 return hireDate;
30 }
31 public void setHireDate(Date hireDate) {
32 this.hireDate = hireDate;
33 }
34 public String getEmail() {
35 return email;
36 }
37 public void setEmail(String email) {
38 this.email = email;
39 }
40 public String toString() {
41 StringBuffer sb = new StringBuffer();
42 sb.append("First: ").append(getFirstName());
43 sb.append(" - Last: ").append(getLastName());
44 sb.append(" - Date: ").append(getHireDate());
45 sb.append(" - Email: ").append(getEmail());
46 return sb.toString();
47 }
48}
Lors de la mise en œuvre de votre "vraie" application avec une couche de persistance, ce POJO est
celui en tant qu'entité JDO/JPA.
Créer une classe Converter pour votre entité
J'encapsule généralement toute la transformation dans une classe de convertisseur, de sorte que je ne
couple pas directement ma classe métier au mécanisme de sérialisation. (Donc je fais ça pour les
classes et les listes de classes). Ainsi, au lieu d'ajouter les annotations JAXB à la classe Employee elle-
même, créons une classe EmployeeConverter qui sera responsable de la transformation et utilisée par
votre service REST.
01package com.ensem.employee.service.converter;
02
03import java.util.Date;
04import javax.xml.bind.annotation.XmlElement;
05import javax.xml.bind.annotation.XmlRootElement;
06import com.ensem.employee.service.model.Employee;
07
08@XmlRootElement(name = "employee")
09public class EmployeeConverter {
dix private Employee entity = null;
11 public EmployeeConverter() {
12 entity = new Employee();
13 }
14
15 public EmployeeConverter(Employee entity) {
16 this.entity = entity;
17 }
18
19 @XmlElement
20 public String getFirstName() {
21 return entity.getFirstName();
22 }
23
24 @XmlElement
25 public String getLastName() {
26 return entity.getLastName();
27 }
28
29 @XmlElement
30 public Date getHireDate() {
31 return entity.getHireDate();
32 }
33
34 @XmlElement
35 public String getEmail() {
36 return entity.getEmail();
37 }
38
39 public Employee getEmployee() {
40 return entity;
41 }
42
43 public void setFirstName(String firstName) {
44 entity.setFirstName(firstName);
45 }
46
47 public void setHireDate(Date hireDate) {
48 entity.setHireDate(hireDate);
49 }
50
51 public void setLastName(String email) {
52 entity.setEmail(email);
53 }
54
55 public void setEmail(String lastName) {
56 entity.setLastName(lastName);
57 }
58}
Vous pouvez maintenant mettre à jour votre service pour utiliser cette classe utilitaire/convertisseur
pour renvoyer un objet XML ou JSON en fonction du type de contenu de la requête.
Ajoutez la prise en charge de JSON et XML à votre service REST
Vous devez changer la classe EmployeeRessource, changer la signature et ajouter de nouvelles
annotations de la méthode getEmployee().
L'annotation que vous ajoutez :
• @Produces({“application/xml”, “application/json”}) : indique quel type de contenu sera
produit par le service. Selon le type de demande.
• @Path(“/employee/{employeeEmail}/”) : changez le Path pour indiquer un paramètre Path,
ici par exemple l'URL peut accepter un email dans l'URI – pas le meilleur exemple, mais vous
avez compris…
• public EmployeeConverter getEmployee( @PathParam ("employeeEmail") String email) :
changez le type retourné par la méthode et prenez un paramètre comme String qui
correspond au paramètre Path défini dans l'annotation @Path
Voici le code complet de la classe :
01package com.ensem.employee.service.rest.impl;
02
03import javax.ws.rs.Path;
04import javax.ws.rs.GET;
05import javax.ws.rs.PathParam;
06import javax.ws.rs.Produces;
07import com.ensem.employee.service.converter.EmployeeConverter;
08import com.ensem.employee.service.model.Employee;
09
dix@Path("/hr/")
11public class EmployeeRessource {
12
13
14 @GET
15 @Produces({"application/xml", "application/json"})
16 @Path("/employee/{employeeEmail}/")
17 public EmployeeConverter getEmployee(
18 @PathParam ("employeeEmail") String email) {
19 //dummy code
20 Employee emp = new Employee();
21 emp.setEmail(email);
22 emp.setFirstName("Hamid");
23 emp.setLastName("Alaoui");
24 EmployeeConverter converter = new EmployeeConverter(emp);
25 return converter;
26 }
}
Testez le service
Vous pouvez maintenant exécuter le serveur localement et tester le service
http://localhost:8080/resources/hr/employee/[email protected]
Cela renverra un document XML.
Si vous souhaitez tester l'appel JSON, vous avez le choix multiple :
• Utilisation de la commande suivante
1tgrall$ curl -H "Accept: application/json" http://localhost:8080/resources/hr/employ
2{"email":"[email protected]","firstName":"Hamid","lastName":"Alaoui"}
• En utilisant un client HTTP qui vous permet de configurer/définir complètement la requête
HTTP, j'utilise le plugin Poster Firefox
• Utiliser du code Javascript dans une application
Vous pouvez répéter le test sur votre application déployée sur Google App Engine.
Conclusion
Dans ce TP, vous avez appris à créer et à déployer un nouveau service REST sur Google App
Engine. Ce service a été créé avec le projet JAX-RS Reference Implementation the Jersey.