I. Qu'est-ce qu'un RESTful webservice ?▲
Les RESTful web services sont devenus de plus en plus populaires. Il s'agit de services basés sur l'architecture REST. Ce type de web service a pour avantages d'être plus léger, plus évolutif et plus facilement maintenable.
L'architecture REST est une architecture s'appuyant sur le protocole HTTP. Elle permet, via une URL, d'effectuer plusieurs types d'opérations sur une ressource.
Ces opérations (utilisant souvent les formats d'échange JSON et XML) sont les suivantes :
- GET
Cette opération permet de récupérer des informations ; - POST
Elle permet de créer une nouvelle entité en fournissant cette nouvelle entité dans le corps de la requête au format JSON ou XML (par exemple) ; - PUT
Elle permet de mettre à jour une entité par les informations fournies au format JSON ou XML (par exemple) dans le corps de la requête ; -
DELETE
Elle permet de supprimer une entité via un identifiant fourni en paramètre.
On peut envoyer une requête à un web service REST par utilisation d'un client REST.
À défaut de développer un tel client REST lors des phases de test de votre futur web service RESTRepresentational State Transfer, on peut utiliser des plugins qui s'installent au sein du navigateur Internet tels :
- RESTClient ( https://addons.mozilla.org/fr/firefox/addon/restclient/ )
Il s'agit d'un plugin pour firefox ; - Advanced REST client (https://chrome.google.com/webstore/detail/advanced-rest-client/hgmloofddffdnphfgcellkdfbfbjeloo )
Il s'agit d'un plugin pour Chrome.
Il existe un plugin client REST pour la plupart des navigateurs.
Ces clients REST permettent de fournir, en paramètre, le format d'échange des données dans l'entête HTTP en indiquant le « content-type ». Par exemple, voici une capture d'écran de RESTClient :
Afin d'accéder à un RESTful web service, il suffit de saisir une URL. Dans l'exemple que nous allons développer dans ce tutoriel, l'adresse de notre web service est la suivante : http://localhost:8181/cxf/olivier/Cette adressereprésente ce qu'on appelle le « endpoint » (point terminal) de notre web service.
À partir de ce endpoint, on pourra accéder aux ressources - customers ou orders - via les URL suivantes :
http://localhost:8181/cxf/olivier/customers/
ou
http://localhost:8181/cxf/olivier/orders/
Il suffit ensuite de choisir, dans le client REST, la méthode d'accès à la ressource (GET, POST, PUT, DELETE), de fournir éventuellement un identifiant dans l'URLUniform Resource Locator pour identifier l'entité à laquelle on souhaite accéder et/ou de fournir éventuellement le corps (body) du message que l'on souhaite transmettre (au format JSON ou XML par exemple - ce format dépend du header HTTP qu'on a renseigné).
II. Qu'est-ce que KARAF ?▲
Karaf est un serveur d'application basé sur les spécifications OSGIOpen Services Gateway Initiative. Ces spécifications définissent un modèle de développement dans lequel les applications sont composées de plusieurs composants. Ces spécifications permettent aux composants de cacher leur implémentation aux autres composants en communiquant à l'aide de services partagés entre tous les composants.
Karaf est composé, entre autres d'un module appelé « Blueprint ».
Blueprint fournit un framework d'injection de dépendances pour OSGIOpen Services Gateway Initiative et a été standardisé par l'alliance OSGIOpen Services Gateway Initiative. Il consiste à travailler avec la nature dynamique des composants OSGIOpen Services Gateway Initiative, où les services peuvent devenir disponibles ou indisponibles à n'importe quel moment.
Blueprint permet, via un container, de superviser l'état des composants dans le framework et d'accomplir des actions en fonction de leur état.
Un composant est considéré être un composant Blueprint à partir du moment où il contient un ou plusieurs fichiers XML Blueprint. Ces fichiers XML sont localisés sous le répertoire OSGI-INF/blueprint comme nous le verrons plus tard.
Dès que Blueprint a déterminé qu'un composant est un composant Blueprint, il crée un container Blueprint basé sur le nom de ce composant. Ce container Blueprint est responsable de :
- parser les fichiers XML Blueprint ;
- instancier les composants ;
- relier les composants entre eux ;
- enregistrer les services ;
- chercher les références des autres services.
Pour plus d'informations sur Blueprint, voir le site officiel : http://aries.apache.org/modules/blueprint.html
Le site officiel de Apache Karaf est le suivant : http://karaf.apache.org/
Les avantages de OSGIOpen Services Gateway Initiative sont présentés sur le site officiel du consortium : http://www.osgi.org/Main/HomePage
III. Problématique▲
Maintenant que nous avons posé les bases du fonctionnement des architectures REST, OSGI et du fonctionnement de Karaf, il peut être intéressant de savoir comment développer un RESTful web service en JAVA sous Eclipse avec un minimum de configuration et en gagnant donc un maximum de temps.
Nous utiliserons, pour cela, un archetype MAVEN ainsi que le framework de services open source « Apache CXF ». CXF aide à construire et développer des services en utilisant des API comme JAX-WS et JAX-RS. Dans notre cas, nous utiliserons JAX-RS.
Le but de ce projet est de créer une application simple de gestion de clients et de commandes.
IV. Configuration logicielle▲
V. Configuration d'Eclipse et de MAVEN▲
-
Il convient d'abord de configurer correctement le MAVEN embarqué dans Eclipse. Pour cela, allez dans Windows ? Preferences ? Maven ? User Settings et vérifiez le répertoire qui apparaît dans la section « User Settings » (ci-dessous, « C:\Users\orozier\.m2\settings.xml »)
-
Créez dans le répertoire « .m2 » (à adapter selon vos besoins) un fichier setting.xml et remplissez-le de la manière suivante :
setting.xmlSélectionnez1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.<settingsxmlns="http://maven.apache.org/SETTINGS/1.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd"><localRepository>${user.home}/.m2/repository</localRepository><interactiveMode>true</interactiveMode><usePluginRegistry>false</usePluginRegistry><offline>false</offline><pluginGroups/><servers/><proxies><proxy><id>1</id><active>true</active><protocol>http</protocol><host>proxy.XXXXX</host><!—Écrire le nom de votre proxy--><port>8080</port><!—Écrire le port de votre proxy--><nonProxyHosts>localhost|127.0.0.1</nonProxyHosts></proxy><proxy><id>2</id><active>true</active><protocol>https</protocol><host>proxy.XXXXX</host><!—Écrire le nom de votre proxy--><port>8080</port><!—Écrire le port de votre proxy--><nonProxyHosts>localhost|127.0.0.1</nonProxyHosts></proxy></proxies><profiles/><activeProfiles/></settings> -
Afin de voir le repository de MAVEN dans Eclipse, allez dans le menu Windows ? Show view ?Other ?Maven ?Maven Repository.
L'onglet « Maven Repositories » apparaît alors. - Dans l'arborescence, allez dans « Global Repositories » et cliquez droit sur « central (https://repo.maven.apache.org/maven2) » et choisissez « Rebuild index »
L'intégralité du repository Maven apparaît quelques instants plus tard, ce qui signifie que Maven est correctement configuré. Si ce n'est pas le cas, un fichier log est disponible sous le workspace d'Eclipse dans le répertoire « \.metadata\.plugins\org.eclipse.m2e.logback.configurator\ ».
VI. Création d'un nouveau projet Maven à l'aide de l'archetype karaf-blueprint▲
Nous avons vu, plus haut, que Karaf s'appuyait sur Blueprint. Nous allons donc chercher un archetype MAVEN adapté à Blueprint afin de nous éviter des efforts de configuration. Nous n'aurons donc plus qu'à adapter le fichier XMLeXtensible Markup Language de Blueprint selon nos besoins.
-
File ? New ? Maven Project
-
Sur la fenêtre qui s'affiche, cliquez sur le bouton « Next »
-
Dans le champ « Filter », saisissez « blueprint » puis, dans la liste qui apparaît, choisissez la ligne correspondant à « karaf-blueprint-archetype » puis cliquez sur le bouton « Next »
-
Renseignez la fenêtre qui apparaît de cette manière :
Group ID : RestFull_Webservice_Karaf
Artefact Id : TestRestServiceKaraf
Version : 0.0.1-SNAPSHOT
Dans la section « Properties available from archetype », attribuez la valeur « RestFull_Webservice_Karaf.TestRestServiceKaraf ».
Puis cliquez sur le bouton « Finish ». -
Un nouveau projet est créé dans l'explorateur de projets d'Eclipse :

-
Renommez l'interface « MyService » et la classe « MyServiceImpl » via un clic droit ?« Refactor » ? « Rename » respectivement en « CustomerService » et « CustomerServiceImpl ».
Le fichier CustomerSerice.java contient donc ceci :CustomerService.javaSélectionnez1.
2.
3.
4.
5.
6.packageRestFull_Webservice_Karaf.TestRestServiceKaraf ;publicinterfaceCustomerService{publicStringecho(String message);}Le fichier CustomerServiceImpl contient ceci :
CustomerServiceImpl.javaSélectionnez1.
2.
3.
4.
5.
6.
7.
8.
9.packageRestFull_Webservice_Karaf.TestRestServiceKaraf ;publicclassCustomerServiceImplimplementsCustomerService{publicStringecho(String message){return"Echo processed: "+message;}} -
Nous allons créer une classe CustomerBean en cliquant droit sur le package « RestFull_Webservice_Karaf.TestRestServiceKaraf » ? « New » ? « Class »
-
Complétez la classe de cette manière :
CustomerBean.javaSélectionnez1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.packageRestFull_Webservice_Karaf.TestRestServiceKaraf;importjavax.xml.bind.annotation.XmlRootElement;/*** La classe CustomerBean est un objet JAVA contenant des méthodes get et set*<p/>* En ajoutant l'annotation @XmlRootElement, nous offrons la possibilité à JAXB de transformer cet objet en document XML et inversement.*<p/>* La représentation XML d'un customer ressemblera à ceci :*<Customer>*<id>123</id>*<name>Olivier</name>*</Customer>*/@XmlRootElement(name="Customer")publicclassCustomerBean{privatelongid;privateString name;publiclonggetId(){returnid;}publicvoidsetId(longid){this.id=id;}publicStringgetName(){returnname;}publicvoidsetName(String name){this.name=name;}} -
De la même manière, ajoutez les classes OrderBean, Product et Products.
-
Dans le fichier pom.xml, ajoutez les lignes suivantes entre la balise fermante </description> et la balise ouvrante <build> afin d'ajouter les bibliothèques nécessaires au webservice en tant que dépendances Maven :
pom.xmlSélectionnez1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.<properties><cxf.version>3.1.3</cxf.version><osgi.version>6.0.0</osgi.version><project.build.outputEncoding>UTF-8</project.build.outputEncoding></properties><dependencies><dependency><groupId>org.osgi</groupId><artifactId>org.osgi.core</artifactId><version>${osgi.version}</version><scope>provided</scope></dependency><dependency><groupId>org.apache.cxf</groupId><artifactId>cxf-rt-frontend-jaxrs</artifactId><version>${cxf.version}</version><scope>provided</scope></dependency><dependency><groupId>org.apache.cxf</groupId><artifactId>cxf-rt-frontend-jaxws</artifactId><version>${cxf.version}</version><scope>provided</scope></dependency><dependency><groupId>org.apache.cxf</groupId><artifactId>cxf-rt-transports-http</artifactId><version>${cxf.version}</version><scope>provided</scope></dependency><dependency><groupId>org.apache.cxf</groupId><artifactId>cxf-rt-transports-http-jetty</artifactId><version>${cxf.version}</version><scope>provided</scope></dependency></dependencies>Le contenu de la balise <osgi.version> dépendra de la version de Karaf utilisée. Les matrices de compatibilité sont disponibles ici :
Pour Karaf 4.0.X :
http://karaf.apache.org/index/documentation/karaf-dependencies/karaf-deps-4.0.x.html
Pour Karaf 3.0.X :
http://karaf.apache.org/index/documentation/karaf-dependencies/karaf-deps-3.0.x.html
Pour Karaf 2.4.X :
http://karaf.apache.org/index/documentation/karaf-dependencies/karaf-deps-2.4.x.html
Pour Karaf 2.3.X :
http://karaf.apache.org/index/documentation/karaf-dependencies/karaf-deps-2.3.x.html
Il suffit, dans le tableau proposé dans chacun des liens ci-dessus, de regarder la ligne « OSGI ».
Dès lors, Karaf utilisera le repository Maven pour récupérer les bibliothèques nécessaires à notre RESTful web service.
-
Dans le fichier pom.xml, supprimez la ligne :
pom.xmlSélectionnez1.<Export-Package>RestFull_Webservice_Karaf.TestRestServiceKaraf *;version=${project.version}</Export-Package>La balise « Export-Package » permet d'indiquer les packages qui seront exportés afin que d'autres Web Service puissent utiliser les interfaces et les classes de ce package lors de leur exécution. Dans notre cas, aucun Web Service n'aura à appeler de package, la balise « Export-Package » n'est donc pas nécessaire.
-
Configurez le fichier src/main/resources/OSGI-INF/blueprint/my-service.xml de la manière suivante :
my-service.xmlSélectionnez1.
2.
3.
4.
5.
6.
7.<blueprintxmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.0.0"xmlns:jaxws="http://cxf.apache.org/blueprint/jaxws"xmlns:jaxrs="http://cxf.apache.org/blueprint/jaxrs"xmlns:cxf="http://cxf.apache.org/blueprint/core"xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd http://cxf.apache.org/blueprint/jaxws http://cxf.apache.org/schemas/blueprint/jaxws.xsd http://cxf.apache.org/blueprint/jaxrs http://cxf.apache.org/schemas/blueprint/jaxrs.xsd http://cxf.apache.org/blueprint/core http://cxf.apache.org/schemas/blueprint/core.xsd"><jaxrs:serveraddress="/olivier"id="someRestService"><jaxrs:serviceBeans><refcomponent-id="CustomerServiceImpl"/></jaxrs:serviceBeans></jaxrs:server><beanid="CustomerServiceImpl"class="RestFull_Webservice_Karaf.TestRestServiceKaraf.CustomerServiceImpl"/></blueprint>Ce fichier permet d'enregistrer le service dans le registre des services et d'indiquer que son implémentation est CustomerServiceImpl. On remarque au passage qu'on y indique notre endpoint (« olivier » ici).
-
Modifiez le fichier CustomerService.java pour y définir la classe CustomerService comme suit :
CustomerService.javaSélectionnez1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.packageRestFull_Webservice_Karaf.TestRestServiceKaraf;importjavax.ws.rs.Consumes;importjavax.ws.rs.DELETE;importjavax.ws.rs.GET;importjavax.ws.rs.POST;importjavax.ws.rs.PUT;importjavax.ws.rs.Path;importjavax.ws.rs.PathParam;importjavax.ws.rs.Produces;importjavax.ws.rs.core.Response;publicinterfaceCustomerService{/*** Cette méthode est mappée à une requête HTTP GET : "http://localhost:8181/cxf/olivier/customers/{id}". La valeur* de {id} sera passée en paramètre à la méthode par utilisation de l'annotation @PathParam.*<p/>* La méthode retournera un objet de la classe CustomerBean par création d'une réponse HTTP. Cet objet sera transformé en XML par JAXB.*<p/>* Par exemple, l'appel de l'URL "http://localhost:8181/cxf/olivier/customers/123" provoquera l'affichage du customer 123 au format XML.*/@GET@Path("/customers/{id}/")@Produces("application/xml")publicCustomerBeangetCustomer(@PathParam("id") String id);/*** Cette méthode est mappée à une requête HTTP PUT. On peut ainsi envoyer la représentation XML d'un objet customerBean.* La représentation XML sera obtenue par transformation d'un CustomerBean par JAXB.*<p/>* Cette méthode met à jour un objet CustomerBean dans notre map locale puis utilise la classe Response pour construire* une réponse HP appropriée : soit OK si la mise à jour a été effectuée avec succès (Traduction du statut HTTP 200/OK)* ou NON MODIFIE si la mise à jour de l'objet CustomerBean a échoué (Traduction du statut HTTP 304/Not Modified).*<p/>* À NOTER : cette méthode utilise la même valeur de @path que la méthode suivante. La méthode HTTP utilisée déterminera* quelle sera la méthode à invoquer**/@PUT@Path("/customers/")@Consumes({"application/xml","application/json"})publicResponseupdateCustomer(CustomerBean customer);/*** Utilisation de la requête HTTP POST permettant d'ajouter un nouveau customer au système en uploadant la représentation XML* d'un objet CustomerBean.* Cette opération sera mappée à la méthode ci-dessous et la représentation XML sera transformée en un objet CustomerBean.*<p/>* Après que cette méthode aura ajouté le client dans la map local, elle utilisera la classe Response pour construire la réponse HTTP* en retournant à la fois l'objet CustomerBean inséré et le statut HTTP 200/OK. Ceci permet de récupérer l'ID du nouvel objet CustomerBean.*<p/>* À NOTER : cette méthode utilise la même valeur de @path que la méthode précédente. La méthode HTTP utilisée déterminera* quelle sera la méthode à invoquer*/@POST@Path("/customers/")@Consumes({"application/xml","application/json"})publicResponseaddCustomer(CustomerBean customer);/*** Cette méthode est mappée à une requête HTTP DELETE du type : "http://localhost:8181/cxf/olivier/customers/{id}".* La valeur pour {id} sera passée en tant que paramètre en utilisant l'annotation @PathParam.*<p/>* Cette méthode utilise la classe Response pour créer une réponse HTTP : soit le statut HTTP 200/OK si l'objet CustomerBean* a été correctement supprimé de la map locale, soit le statut HTTP 304/Not Modified si la suppression a échoué.*/@DELETE@Path("/customers/{id}/")publicResponsedeleteCustomer(@PathParam("id") String id);/*** Cette méthode est mappée à une requête HTTP GET du type : "http://localhost:8181/cxf/olivier/orders/{id}".* La valeur pour {id} sera passée en tant que paramètre en utilisant l'annotation @PathParam.*<p/>* La méthode retournera un objet de la classe Product par création d'une réponse HTTP. Cet objet sera transformé en XML par JAXB.*<p/>* Par exemple, l'appel de l'URL "http://localhost:8181/cxf/olivier/orders/223" provoquera l'affichage du customer 123 au format XML.*/@GET@Path("/orders/{orderId}")@Produces("application/xml")publicOrderBeangetOrder(@PathParam("orderId") String orderId);/*** Cette méthode est mappée à une requête HTTP GET du type : "http://localhost:8181/cxf/olivier/orders/{id}/products/{productId}".* La valeur pour {id} et {productId} sera passée en tant que paramètre en utilisant l'annotation @PathParam.*<p/>* La méthode retournera un objet de la classe Product par création d'une réponse HTTP. Cet objet sera transformé en XML par JAXB.*<p/>* Par exemple, l'appel de l'URL "http://localhost:8181/cxf/olivier/orders/223/products/323/" provoquera l'affichage du customer 123 au format XML.*/@GET@Path("/orders/{orderId}/products/{productId}")@Produces("application/xml")publicProductgetProduct(@PathParam("orderId") String orderId,@PathParam("productId")intproductId);/*** Cette méthode est mappée à une requête HTTP GET du type : "http://localhost:8181/cxf/olivier/orders/{id}/products".* La valeur pour {id} sera passée en tant que paramètre en utilisant l'annotation @PathParam.*<p/>* La méthode retournera un objet de la classe Product par création d'une réponse HTTP. Cet objet sera transformé en XML par JAXB.*<p/>* Par exemple, l'appel de l'URL "http://localhost:8181/cxf/olivier/orders/223/products/323/" provoquera l'affichage du customer 123 au format XML.*/@GET@Path("/orders/{orderId}/products")@Produces("application/xml")publicProductsgetProducts(@PathParam("orderId") String orderId);} -
Modifiez le fichier CustomerServiceImpl.java pour y définir la classe CustomerServiceImpl comme suit :
CustomerServiceImpl.javaSélectionnez1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.packageRestFull_Webservice_Karaf.TestRestServiceKaraf ;importjava.util.HashMap;importjava.util.Map;importjavax.ws.rs.core.Response;importjavax.ws.rs.PathParam;importorg.slf4j.Logger;importorg.slf4j.LoggerFactory;publicclassCustomerServiceImplimplementsCustomerService{privatestaticfinalLogger LOG=LoggerFactory.getLogger(CustomerService.class);longcurrentId=123; Map<Long, CustomerBean>customers=newHashMap<Long, CustomerBean>(); Map<Long, OrderBean>orders=newHashMap<Long, OrderBean>();publicCustomerServiceImpl(){init();}/*** Cette méthode est utilisée par le constructeur pour insérer un objet CustomerBean et un objet OrderBean dans la map locale pour tester.*/finalvoidinit(){LOG.info("Appel de la méthode init de CustomerServiceImpl"); CustomerBean c=newCustomerBean(); c.setName("Olivier"); c.setId(123); customers.put(c.getId(), c); OrderBean o=newOrderBean(); o.setDescription("order 223"); o.setId(223); orders.put(o.getId(), o);}//code retour = 500: ID invalid//code retour = 204: customer non trouvepublicCustomerBeangetCustomer(String id){LOG.info("Appel de getCustomer avec l'identifiant: {}", id);longidNumber=Long.parseLong(id); CustomerBean c=customers.get(idNumber);returnc;}publicResponseupdateCustomer(CustomerBean customer){LOG.info("Mise à jour d'un client dont le nom est : {}", customer.getName()); CustomerBean c=customers.get(customer.getId()); Response r;if(c!=null){customers.put(customer.getId(), customer); r=Response.ok().build();}else{r=Response.notModified().build();}returnr;}publicResponseaddCustomer(CustomerBean customer){LOG.info("Ajout d'un client dont le nom est : {}", customer.getName()); customer.setId(++currentId); customers.put(customer.getId(), customer);returnResponse.ok().type("application/xml").entity(customer).build();}publicResponsedeleteCustomer(String id){LOG.info("Suppression d'un client dont l'identifiant est : {}", id);longidNumber=Long.parseLong(id); CustomerBean c=customers.get(idNumber); Response r;if(c!=null){r=Response.ok().build(); customers.remove(idNumber);}else{r=Response.notModified().build();}returnr;}publicOrderBeangetOrder(String orderId){LOG.info("Récupération de la commande d'identifiant : {}", orderId);longidNumber=Long.parseLong(orderId); OrderBean c=orders.get(idNumber);returnc;}publicProductgetProduct(String orderId,intproductId){LOG.info("Récupération de la commande: {}", orderId);longidNumber=Long.parseLong(orderId); OrderBean c=orders.get(idNumber);//return c;LOG.info("Récupération du produit d'identifiant : "+productId); Product p=c.getProduct(productId);returnp;}publicProductsgetProducts(String orderId){LOG.info("Récupération des produits de la commande : {}", orderId);longidNumber=Long.parseLong(orderId); OrderBean c=orders.get(idNumber);//return c;Products p=c.getProducts();returnp;}} -
Modifiez le fichier OrderBean.java pour y définir la classe OrderBean comme suit :
OrderBean.javaSélectionnez1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.packageRestFull_Webservice_Karaf.TestRestServiceKaraf;importjava.util.HashMap;importjava.util.Map;importjava.util.ArrayList;importjavax.xml.bind.annotation.XmlRootElement;importorg.slf4j.Logger;importorg.slf4j.LoggerFactory;/*** La classe OrderBean est un objet JAVA contenant des méthodes get et set et est aussi utilisée pour les commandes retournées par* la classe CustomerServiceImpl.*<p/>* En ajoutant l'annotation @XmlRootElement, nous offrons la possibilité à JAXB de transformer cet objet en document XML et inversement.*<p/>* La représentation XML pour un OrderBean est la suivante :*<Order>*<id>223</id>*<description>Order 223</description>*</Order>*/@XmlRootElement(name="Order")publicclassOrderBean{privatestaticfinalLogger LOG=LoggerFactory.getLogger(CustomerService.class);privatelongid;privateString description;//private Map<Long, Product> products = new HashMap<Long, Product>();privateProducts products=newProducts();publicOrderBean(){init();}finalvoidinit(){products.setProducts(newArrayList<Product>()); Product p1=newProduct(); p1.setId(323); p1.setDescription("product 323"); Product p2=newProduct(); p2.setId(324); p2.setDescription("product 324"); products.getProducts().add(p1); products.getProducts().add(p2);}publiclonggetId(){returnid;}publicvoidsetId(longid){this.id=id;}publicStringgetDescription(){returndescription;}publicvoidsetDescription(String d){this.description=d;}publicProductgetProduct(intproductId){Product prod=null;for(Product p : products.getProducts()){if(p.getId()==productId){prod=p;}}returnprod;}publicProductsgetProducts(){returnproducts;}} -
Modifiez le fichier Product.java pour y définir la classe Product comme suit :
Product.javaSélectionnez1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.packageRestFull_Webservice_Karaf.TestRestServiceKaraf;importjavax.xml.bind.annotation.XmlRootElement;/*** La classe Product est un objet JAVA contenant des méthodes get et set*<p/>* En ajoutant l'annotation @XmlRootElement, nous offrons la possibilité à JAXB de transformer cet objet en document XML et inversement.*<p/>* La représentation XML d'un Product ressemblera à ceci :**<Product>*<id>10010</id>*<description>produit 1</description>*</Product>*/@XmlRootElement(name="Product")publicclassProduct{privatelongid;privateString description;publiclonggetId(){returnid;}publicvoidsetId(longid){this.id=id;}publicStringgetDescription(){returndescription;}publicvoidsetDescription(String d){this.description=d;}} - Modifiez le fichier Products.java pour y définir la classe Products comme suit :
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
package RestFull_Webservice_Karaf.TestRestServiceKaraf;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import java.util.List;
/**
* La classe Product est un objet JAVA contenant une liste de produits.
* <p/>
* En ajoutant l'annotation @XmlRootElement, nous offrons la possibilité à JAXB de transformer cet objet en document XML et inversement.
*
* <Products>
* <Product>
* <id>10010</id>
* <description>Produit 1</description>
* </Product>
* <Product>
* <id>10011</id>
* <description>Produit 2</description>
* </Product>
* <Products>
*/
@XmlRootElement(name = "Products")
@XmlAccessorType (XmlAccessType.FIELD)
public class Products
{
@XmlElement(name = "Product")
private List<Product> productsList = null;
public List<Product> getProducts()
{
return productsList;
}
public void setProducts(List<Product> productsList)
{
this.productsList = productsList;
}
}
VII. Compilation et Build▲
-
Cliquez droit sur le projet ? Run as ?Maven build
-
Dans le champ « Goals », écrivez « clean install », puis appuyez sur le bouton run
- Le message suivant apparaît alors :
On peut y lire dans quel répertoire récupérer l'archive jar.
Il s'agit du répertoire que vous configurez dans Eclipse via Windows ? Preferences ? Maven ?User Settings
VIII. Installation et configuration de karaf▲
- Téléchargez et installez Karaf 4.0.2 sur le site http://karaf.apache.org/index/community/download.html
- Exécutez le fichier « karaf.bat » qui se situe dans le répertoire « bin ».
- Installez éventuellement la console d'administration via la commande :
feature:install webconsole - À l'issue de cette installation, on peut accéder à la console d'administration de karaf via l'UUniform Resource LocatorRL : http://localhost:8181/system/console/
Par défaut, l'utilisateur est karaf et le mot de passe est karaf. - Ajoutez le repository cxf afin que Karaf puisse installer les caractéristiques propres à cxf. Pour cela, tapez la commande suivante dans l'invite de commande :
feature:repo-add cxf 3.0.6 - Tapez la commande suivante afin de vérifier que les caractéristiques cxf sont prêtes à être installées :
feature:repo-list
Une ligne « cxf-3.0.6 » doit alors apparaître. - Si la ligne cxf-3.0.6 apparaît, l'installation peut être faite via la commande :
feature:install cxf -
Vérifiez l'installation via la commande suivante :
feature:list | grep cxf -
Déposez le fichier jar créé plus haut dans le répertoire « deploy » de Karaf puis redémarrez Karaf.
-
On peut désormais voir si notre OSGI bundle a été installé avec la commande :
Bundle:listSur la capture d'écran ci-dessus, on peut voir la ligne correspondant à notre bundle « TestRestServiceKara Blueprint Bundle ». Ce libellé peut-être configuré dans le fichier pom.xml avant de construire l'archive Jar dans Eclipse. Il s'agit alors de modifier le contenu des balises :
xml
<name>TestRestServiceKaraf Blueprint Bundle</name>
<description>TestRestServiceKaraf OSGi blueprint bundle project.</description> - Via la commande :
cxf:list-endpoints
on peut voir les endpoints cxf qui ont été installés. On peut y voir le nôtre :
IX. Conclusion▲
Comme nous venons de le voir, le développement de RESTful web service pour Karaf est très rapide et très simple sous Eclipse, notamment avec l'utilisation de MAVEN et de l'archetype « karaf-blueprint ».
Cette méthode n'a rien à envier à Talend ESB.
Le code source de l'exemple dont il est question dans ce tutoriel est disponible à l'adresse suivante : olivier-rozier.developpez.com/tutoriels/rest/restful-webservice-karaf-eclipse/fichiers/TestRestServiceKaraf.zip
Nous venons d'étudier les bases de la création d'un RESTful web service pour Karaf .
Il serait intéressant désormais de connaître la manière de développer un RESTful web service découpé en couches applicatives et la manière d'accéder à une base de données en utilisant les Datasource et Datasource factory de Karaf. C'est ce que nous étudierons dans le tutoriel « Tutoriel pour développer et déployer un service Web RESTFUL OSGI multibundle sous Eclipse et Karaf ».
Je tiens à remercier Mickaël Baron pour la relecture technique de cet article ainsi que Claude Leloup pour la relecture orthographique.
Index▲
| - A - | Eclipse Mars (1) | - K - | PUT (1), (2) |
| archetype (1) | endpoint (1) | Karaf (1), (2), (3), (4), (5), (6), (7), (8) | - R - |
| archetype MAVEN (1), (2) | - G - | Karaf . (1) | REST (1), (2), (3), (4), (5), (6), (7), (8), (9), (10) |
| - B - | GET (1), (2) | Karaf 4.0.2 (1) | RESTful web service (1), (2), (3), (4) |
| Blueprint (1), (2), (3), (4), (5), (6), (7), (8), (9), (10), (11), (12), (13) | - H - | - M - | - U - |
| - C - | HTTP (1), (2), (3) | MAVEN (1), (2), (3) | URL (1), (2), (3) |
| CXF (1) | - J - | - O - | - X - |
| - D - | JAVA (1) | omman (1) | XML (1), (2), (3), (4), (5), (6), (7) |
| DELETE (1), (2) | JAX-RS (1), (2) | OSGI (1), (2), (3) | |
| - E - | JAX-WS (1) | - P - | |
| Eclipse (1), (2), (3), (4), (5), (6), (7) | JSON (1), (2), (3), (4) | POST (1), (2) |


















