Toujours avec le même leitmotiv « Droit à l’Essentiel », nous allons créer un service web en utilisant CXF et Spring, du développement java.

Cependant et à la différence des articles précédents sur le sujet, nous allons aborder ici l’architecture REST et donc développer un web service basée sur cette architecture.

L’idée est que cet article vous permette d’être autonome en très peu de temps.

Le déploiement du service web qui sera créé sera déployé en local. En ce qui concerne le client du web service, celui-ci est l’objet d’un autre article.

 

Prérequis

– Java;
– Eclipse (un minimum de connaissance sur eclipse);
– Spring (connaissance non obligatoire);
– Maven installé et configuré;
– Tomcat installé et configuré;
– Firefox, et son plugin Client REST pour nous permettre de tester les différentes méthodes.

 

Web service, c’est quoi ?

C’est une application (utilisant le protocole http) dont on peut invoquer diverses fonctionnalités ou opérations à distance (par réseau).

Le réseau peut être public (internet) ou privé (intranet), le web service peut aussi intégrer des mécanismes de sécurité permettant de privatiser son accès sur un réseau public.

ws

 
[s2If !is_user_logged_in() || current_user_is(s2member_level0)]

Pour lire la suite, devenez
abonné Premium de Faire des Jeux.
5€ seulement pour avoir accés à tous les articles pendant une année !


[s2Member-PayPal-Button level= »1″ ccaps= » » desc= »Abonné premium » ps= »paypal » lc= » » cc= »EUR » dg= »0″ ns= »1″ custom= »www.faire-des-jeux.com » ta= »0″ tp= »0″ tt= »D » ra= »5″ rp= »1″ rt= »Y » rr= »BN » rrt= » » rra= »1″ image= »https://www.video-game-codeur.fr/download/paypalbtn/btn_paypalxpressCheckout.gif » output= »button » /]

[/s2If]

[s2If current_user_can(access_s2member_level1)]
 

CXF c’est quoi ?

CXF est un projet open source de la fondation Apache (http://cxf.apache.org/).

Ce framework permet de développer aisément des web services SOAP grâce à l’api JAX-WS ou REST grâce à l’api JAX-RS.

Cet article s’arrêtera à l’utilisation de JAX-RS.

 

REST, c’est quoi ?

Hé oui, le strict minimum de concepts à savoir. REST est l’acronyme anglais de REpresentational State Transfer.

Ce n’est pas un protocole, mais simplement une manière d’utiliser l’architecture relative au protocole HTTP.

Nous allons nous intéresser aux méthodes relatives à ce protocole (pensez à la propriété method de la balise HTML FORM), et plus particulièrement les méthodes GET, POST, PUT, DELETE.

Chacune de ces méthodes va correspondre à un type d’action sur une ressource (un élément de votre couche métier comme par exemple un compte client) :
GET va permettre d’invoquer une ressource pour l’afficher, afficher un compte client;
POST va permettre de créer une ressource, créer un compte client;
PUT va permettre de modifier une ressource, modifier un compte client;
DELETE va permettre de supprimer une ressource, supprimer un compte client.

Ne vous concentrez que sur ces quatre méthodes, ne vous encombrez pas l’esprit avec les autres, elles sont superflues dans le cadre de cet article. Sachez juste qu’elles existent (HEAD, CONNECT, TRACE, OPTIONS).

 

Création du webservice

Architecture de notre projet

Il s’agit ici de créer un service web donc disponible via le protocole http. De ce fait, le projet à créer est un projet de type web, et le livrable sera un fichier war à déployer sous Tomcat.

L’utilisation de maven impose l’organisation des dossiers du projet web. Pour rappel :
– src/main/java : répertoire des classes java;
– src/main/webapp: répertoire de la webapp qui va héberger le webservice;
– src/test/java : répertoire des classes de test.

Les dépendances MAVEN, le fichier pom.xml

Les dépendances Spring et CXF à déclarer dans le pom.xml.

<dependencies>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>3.0.5.RELEASE</version>
  </dependency>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-beans</artifactId>
    <version>3.0.5.RELEASE</version>
  </dependency>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>3.0.5.RELEASE</version>
  </dependency>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>3.0.5.RELEASE</version>
  </dependency>
  <dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-rt-frontend-jaxws</artifactId>
    <version>${cxf.version}</version>
  </dependency>
  <dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-rt-transports-http</artifactId>
    <version>${cxf.version}</version>
  </dependency>
  <dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-rt-frontend-jaxrs</artifactId>
    <version>${cxf.version}</version>
  </dependency>
</dependencies>

 

Le pom.xml dans son intégralité

<project xmlns="http://maven.apache.org/POM/4.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
  http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>kezen</groupId>
  <artifactId>CXF-REST</artifactId>
  <version>1.0.0-SNAPSHOT</version>
  <packaging>war</packaging>
  <properties>
    <buildWebappDirectory>${basedir}/target/webapp</buildWebappDirectory>
    <cxf.version>2.2.3</cxf.version>
  </properties>
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>2.1</version>
        <configuration>
          <source>1.6</source>
          <target>1.6</target>
        </configuration>
      </plugin>
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>tomcat-maven-plugin</artifactId>
        <version>1.1</version>
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-eclipse-plugin</artifactId>
        <version>2.8</version>
        <configuration>
          <useProjectReferences>false</useProjectReferences>
          <wtpversion>1.5</wtpversion>
        </configuration>
      </plugin>
    </plugins>
  </build>
  <dependencies>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>3.0.5.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-beans</artifactId>
      <version>3.0.5.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>3.0.5.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>3.0.5.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.apache.cxf</groupId>
      <artifactId>cxf-rt-frontend-jaxws</artifactId>
      <version>${cxf.version}</version>
    </dependency>
    <dependency>
      <groupId>org.apache.cxf</groupId>
      <artifactId>cxf-rt-transports-http</artifactId>
      <version>${cxf.version}</version>
    </dependency>
    <dependency>
      <groupId>org.apache.cxf</groupId>
      <artifactId>cxf-rt-frontend-jaxrs</artifactId>
      <version>${cxf.version}</version>
    </dependency>
  </dependencies>
</project>

Dans ce fichier, il est indiqué :
– la forme du livrable (war en section packaging);
– la version de la jvm source à partir de laquelle est développé le service;
– la version de la jvm cible sur laquelle le service web est censé fonctionner (section build). Modifier la version du target build en fonction de la version jvm sous laquelle tourne votre Tomcat;
– une référence au plugin wtp, pour une meilleure intégration du développement dans eclipse.

Les packages

Après avoir créé le projet Java (appelons le WSTimeService) sous Eclipse, créer un package kezen.rs.

Le service à proprement parler

Nous allons créer un web service REST qui renverra simplement la date et l’heure.

Ce cas ne présente aucune ressource à créer, modifier ou supprimer.

Juste une ressource à afficher. C’est pour cette raison que nous utiliserons la méthode GET.

Nous allons coder notre webservice dans une classe à part entière que nous appellerons TimeService dans laquelle sera intégrée la méthode qui sera exécutée à l’appel du service. Méthode que nous appelons getDateTime.

Le code de la classe TimeService

package fdj.rs;

import java.util.Calendar;
import java.util.Locale;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import org.springframework.format.datetime.DateFormatter;
import org.springframework.stereotype.Service;

@Service("timeService")
@Path("/time/")
public class TimeService {

   @GET
   @Produces("text/plain")
   public String getDateTime()
   {
     DateFormatter formatter = new DateFormatter("dd/MM/yyyy hh:mm:ss");
     return formatter.print(Calendar.getInstance().getTime(), Locale.getDefault());
   }
}

Dans l’exemple ci-dessus, les annotations :
– « @Service » sur la classe, indique que notre classe est un web service;
– « @Path » sur la classe, indique que le chemin par lequel accéder au web service;
– « @GET » sur la méthode, indique que l’accès au service se fera par le biais de la méthode GET décrite ci-dessus.
– « @Produces(« text/plain ») » sur la méthode, indique le format (qui est ici du texte) dans lequel les données sont renvoyées par la méthode, cela aurait pu être de l’Xml, du Json.

Faites attention à rester cohérent avec les principes REST, ici nous faisons appel à une ressource qui est l’heure. Aucun opération n’est faites sur cette ressource.

 

Configuration Spring et CXF au sein du projet

Pour intégrer Spring au projet web, il suffit d’ajouter au fichier web.xml les clauses suivantes :

<context-param>
 <!-- La localisation du fichier applicationContext.xml -->
 <param-name>contextConfigLocation</param-name>
 <param-value>WEB-INF/applicationContext.xml</param-value>
</context-param>
<!-- Le listener Spring qui va charger le fichier applicationContext.xml -->
<listener>
 <listener-class>
  org.springframework.web.context.ContextLoaderListener
 </listener-class>
</listener>

Même chose pour CXF, il suffit d’ajouter les clauses suivantes (indiquant entre autres via url-pattern, la forme de l’url qui permettra d’accéder au web service [/ws/methodeAppellée]) au fichier web.xml :

<!-- Configuration de CXF -->
<servlet>
 <servlet-name>CXFServlet</servlet-name>
 <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
  <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
 <servlet-name>CXFServlet</servlet-name>
 <url-pattern>/rs/*</url-pattern>
</servlet-mapping>

La directive url-pattern de la balise servlet-mapping indique le chemin racine des web services.

On accède alors au web service via http://monsiteweb/rs.

Cette url, invoquée depuis un browser, permet de lister les webservices disponibles.

 

Configuration du service web sous Spring

Pour pouvoir configurer des services web CXF depuis Spring, voici le fichier « applicationContext.xml » :

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:jaxrs="http://cxf.apache.org/jaxrs"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
       http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
       http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
  <import resource="classpath:META-INF/cxf/cxf.xml"/>
  <import resource="classpath:META-INF/cxf/cxf-extension-jaxrs-binding.xml"/>
  <import resource="classpath:META-INF/cxf/cxf-servlet.xml"/>
  <context:component-scan base-package="kezen"/>
  <jaxrs:server id="restContainer" address="/">
    <jaxrs:serviceBeans>
      <ref bean="timeService"/>
    </jaxrs:serviceBeans>
  </jaxrs:server>
</beans>

– la directive component-scan base-package indique à Spring une configuration par annotations dans le package kezen;
– la directive jaxrs:server a un identifiant et une adresse comme paramètres : address indique le chemin racine des webservices déclarés, on accède alors au web service via http://monsiteweb/rs/. Si nous mettions, au lieu de /, kezen, l’accès se ferait via http://monsiteweb/rs/kezen/ (n’oubliez le rs dans l’url qui a été configuré dans le servlet-mapping);
– la directive jaxrs:serviceBeans référence les web services que vous souhaitez exposer, web services configurés par annotation.
Remarquez que la balise ref bean référence le web service tel qu’il est déclaré dans l’annotation @Service.

 

Compilation

Un simple commande maven va permettre de générer un livrable à déployer sous Tomcat, se placer dans le dossier du projet et lancer la commande suivante:
mvn clean package.

Le livrable sous forme d’un fichier war devrait se trouver dans le dossier target du projet web.

 

Déploiement

L’opération est simple ici aussi, soit vous déposer le fichier directement dans le dossier Tomcat adéquat, soit vous passez par le manager (interface web de Tomcat).

 

Vérification du déploiement

Depuis un browser, taper l’url du web service : http://localhost:8080/CXF-REST-1.0.0-SNAPSHOT/rs/
Devrait apparaitre une page web listant toutes les méthodes publiques du web service.

 

Test du service

Depuis un browser, taper l’url du web service : http://localhost:8080/CXF-REST-1.0.0-SNAPSHOT/rs/time/.
Devrait apparaitre une page web affichant l’heure courante.

 

Les sources

Les sources de l’exemple sont téléchargeables ici.
[/s2If]

 

Conclusion

Espérant que cet article vous sera utile. J’aborderais dans de prochains articles les méthodes POST, PUT, et DELETE.