Toujours avec le même leitmotiv « Droit à l’Essentiel » et toujours en faisant du java, nous allons créer un webservice en utilisant java CXF et Spring. L’idée est que cet article permette d’être autonome en très peu de temps.

Le déploiement du webservice créé sera déployé en local.

 

Prérequis

– Java
– Eclipse (un minimum de connaissance sur eclipse)
– Spring (connaissance non obligatoire)
– Maven installé et configuré
– Tomcat installé et configuré

 

Webservice, 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).

 
[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= »http://www.video-game-codeur.fr/download/paypalbtn/btn_paypalxpressCheckout.gif » output= »button » /]

[/s2If]

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

ws

 

CXF c’est quoi ?

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

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

Cet article s’arrêtera à l’utilisation de JAX-WS, JAX-RS et REST feront l’objet d’un prochain article.

 

SOAP webservice c’est quoi ?

Simple Object Access Protocol, protocole d’accès aux objets simples.
Comme son nom ne l’indique pas, c’est un protocole d’échange d’informations inter-applications basé sur xml.

 

Création du webservice java

Architecture de notre projet

Il s’agit ici de créer un webservice java 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 java;
– src/main/webapp/WEB-INF: répertoire des fichiers de configuration de notre exemple;
– src/test/java : répertoire des classes de test.

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</artifactId>
    <version>2.5.6</version>
  </dependency>
  <!-- Apache CXF dependencies -->
  <dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-rt-frontend-jaxws</artifactId>
    <version>2.2.10</version>
  </dependency>
  <dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-rt-transports-http</artifactId>
    <version>2.2.10</version>
  </dependency>
</dependencies>

Même si dans l’exemple elle est inscrite, la dépendance Spring n’est pas nécessaire puisqu’elle est elle même une dépendance de CXF. Nous pourrions donc très bien retirer la dépendance Spring du fichier pom.xml.

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/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
    <groupId>WSAuthentication</groupId>
    <artifactId>WSAuthentication</artifactId>
    <packaging>war</packaging>
    <version>0.0.1-SNAPSHOT</version>
    <build>
      <plugins>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-compiler-plugin</artifactId>
          <configuration>
            <source>1.6</source>
            <target>1.6</target>
          </configuration>
        </plugin>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-eclipse-plugin</artifactId>
          <version>2.8</version>
        </plugin>
      </plugins>
    </build>
    <dependencies>
      <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring</artifactId>
        <version>2.5.6</version>
      </dependency>
      <!-- Apache CXF dependencies -->
      <dependency>
        <groupId>org.apache.cxf</groupId>
        <artifactId>cxf-rt-frontend-jaxws</artifactId>
        <version>2.2.10</version>
      </dependency>
      <dependency>
        <groupId>org.apache.cxf</groupId>
        <artifactId>cxf-rt-transports-http</artifactId>
        <version>2.2.10</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;
– et 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.

Depuis une console, placez vous dans le dossier de votre projet à sa racine et exécutez la commande :

mvn eclipse:clean eclipse:eclipse

Cette commande téléchargera les dépendances listées dans le fichier pom.xml et formatera votre projet selon la norme MAVEN.

 

Le développement

Les packages

Après avoir créé le projet Java (appelons le WSAuthentication) sous Eclipse, créer deux packages distincts:
– wsinterface qui comportera l’interface (la description) de notre service web et;
– wsimplementation qui en sera l’implémentation.

Sous Eclipse, faire un clic droit sur votre projet, puis New/Package comme suit :

EclipsePkg1

Indiquer le nom du package (wsinterface), puis cliquer sur le bouton « Finish »

EclipsePkg2

Répéter l’opération pour le package wsimplementation.

Le service à proprement parler

Le webservice est très simple. Pour l’exemple, il s’agit d’implémenter une authentification qui, à partir d’un identifiant et un mot de passe, avalise ou non un accès.

La première chose à faire est d’écrire l’interface qui décrit le service: la signature de la classe qui implémentera l’interface du webservice. Appelons cette interface « AuthenticationService ».

Enfin, il faut écrire la signature de la méthode qui sera invoquée pour avaliser ou non l’accès. Appelons cette méthode « getAccess » qui prend en paramètre un identifiant et un mot de passe.

Le code de l’interface

package wsinterface;

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;

@WebService
public interface AuthenticationService 
{
  @WebMethod
  public Boolean getAccess(
    @WebParam(name="login") String login, 
    @WebParam(name="password") String password);
}

Dans l’exemple ci-dessus, les annotations :
– « @WebService » indique que notre classe est un webservice java;
– « @WebMethod » indique que la méthode sera exposée aux clients lors du déploiement;
– « @WebParam » indique que le paramètre est une information donnée par le client, l’invocation du service nécessite (exigence) tous les WebParam indiqués, cependant cette annotation, bien que fortement recommandée, n’est pas obligatoire. En effet, sans cette annotation vos paramètres porteront de doux noms tels que argN, ce qui peut en rendre la lecture et/ou la compréhension chaotique.

Une fois l’interface créée, celle-ci peut être implémentée afin d’écrire dans le détail ce que va faire le webservice pour répondre au besoin. L’implémentation très simple, va consister ici à répondre positivement pour un couple (identifiant, mot de passe) particulier (tarzan, jane).

Le code de l’implémentation

package wsimplementation;

import javax.jws.WebService;
import wsinterface.AuthenticationService;

@WebService(
  endpointInterface = "wsinterface.AuthenticationService", 
  serviceName = "authenticationService")
public class AuthenticationServiceImpl implements AuthenticationService 
{
  public Boolean getAccess(String login, String password) 
  {	
    if ( login.equals("tarzan") && password.equals("jane")) 
    {
      return Boolean.TRUE;
    }

    return Boolean.FALSE;
  }
}

Dans l’exemple ci-dessus, l’annotation « @WebService » utilise les paramètres :
endpointInterface pour indiquer l’interface qui est implémentée;
serviceName pour indiquer le nom du service exposé.

 

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 webservice java [/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>/ws/*</url-pattern>
</servlet-mapping>

 

Configuration du service web sous Spring

Pour pouvoir configurer des webservices java CXF depuis Spring, ajouter les directives suivantes au fichier « applicationContext.xml » :

<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />

Pour configurer et déclarer le webservice java créé préalablement, il suffit d’ajouter dans ce même fichier une directive jaxws:endpoint comme suit, dans laquelle on indique la classe d’implémentation du service web ainsi que l’url qui nous permettra d’y accéder :

<jaxws:endpoint id="authentication" 
 implementor="wsimplementation.AuthenticationServiceImpl" 
 address="/authentication">
</jaxws:endpoint>

 

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 webservice java : http://localhost:8080/WSAuthentication-0.0.1-SNAPSHOT/ws/
Devrait apparaitre une page web listant toutes les méthodes publiques du webservice java comme suit :

out_CXFSoap

 

Les difficultés que vous pourriez rencontrer

– Si vous avez une erreur qui ressemble à :

GRAVE: The web application [/WSAuthentication-0.0.1-SNAPSHOT] created a ThreadLocal with key of type .... but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.

Cette erreur provient du composant de surveillance des fuites mémoire de Tomcat. C’est un bug corrigé depuis la version 7.0.6. Pour éviter cette erreur, il vous suffit de le désactiver en mettant en commentaire dans le fichier /conf/server.xml la ligne Listener className=’org.apache.catalina.core.JreMemoryLeakPreventionListener’.

– Si vous avez une erreur qui ressemble à :

GRAVE: Context initialization failed .... Instantiation of bean failed; .... nested exception is java.lang.LinkageError: JAXB 2.0 API is being loaded from the bootstrap classloader, but this RI (from jar:file:/C:/mesTests/apache-tomcat-7.0.26/webapps/WSAuthentication-0.0.1-SNAPSHOT/WEB-INF/lib/jaxb-impl-2.1.13.jar!/com/sun/xml/bind/v2/model/impl/ModelBuilder.class) needs 2.1 API. ....

Cette erreur provient d’un conflit de librairies Java : la librairie JAXB version 2.0 est intégrée à Java version 6 jusque l’Update 3. A partir de la Version 6 Update 4, c’est la version 2.1 qui est intégrée. La version 2.2 est intégrée à la Version 7. Le projet utilisant JAXB en version 2.1, si vous avez un SDK Java Version 6 inférieure à l’Update 4, cette erreur va probablement apparaître. Pour corriger cette erreur, il vous suffit de monter en version votre SDK Java : utiliser une version Java supérieure à la Version 6 Update 3.

 

Sources du projet

Vous pouvez télécharger les sources complet du projet CXFSoap. N’oubliez pas avant le déploiement d’exécuter la commande MAVEN pour télécharger les dépendances :

mvn eclipse:clean eclipse:eclipse

[/s2If]

 

Conclusion

J’espère avoir été clair dans mon propos. Il nous reste maintenant à montrer comment invoquer le webservice java créé, objet d’un autre article.

 

Avez vous rencontré des difficultés lors de l’implémentation de vos webservices ? Utilisez vous un autre framework que CXF pour implémenter vos WS ?