Utiliser un Web Service en Java avec Eclipse

Lorsqu'on veut utiliser un Web Service à partir d'une application Java, il y a plusieurs opérations relativement techniques à enchaîner pour obtenir un fonctionnement correct de l'ensemble. Surtout si on utilise un IDE comme Eclipse.
Ces opérations ne sont pas effectuées suffisamment fréquemment. Et, "une fois que ça marche", on oublie ce qu'il faut faire, lorsque qu'il faut accéder à un nouveau service. Ce qui génère une perte de temps.
Le présent article décrit les différentes opérations à effectuer, dans l'IDE Eclipse, pour pouvoir consommer un Web Service distant à partir d'une application Java. Il faut entendre "application Java" au sens large. Ce peut être n'importe que type de projet Java (application Console, application graphique SWT, ou site Web) que permet l'IDE.

Création d'un Proxy sur le Web Service

La première étape est de créer un proxy Java sur le Web Service Distant. Il s'agit d'un projet Java Eclipse dédié à cet effet dans lequel sont importées la définition Java de toutes les objets exposés par le Web Service sous forme de classes Java.
Avant de procéder à la création du Proxy, il faut s'assurer que l'url du Web Service est accessible et qu'elle fonctionne. Ce peut être effectué grâce à un outil comme SOAPUI développé par la société SmartBear dont une version gratuite limité, mais qui convient pour le test, est téléchargeable à l'adresse https://www.soapui.org/downloads/soapui.html.

Création du projet Java pour le proxy

Le projet Java relatif au proxy d'un Web Service se crée comme un projet Java Eclipse standard, à la différence qu'on le crée vide (sans la classe de la fonction main d'une application java) :
  • Faire un clic-droit dans l'onglet Package Explorer pour lancer la commande New/Java Project.
  • Dans la fenêtre Create a Java Project :
    • Saisir le nom du projet Proxy dans Project Name (par exemple WSAnnuaire-Proxy).
    • Dans la boite JRE, choisir le même environnement JAVA dans lequel l'application qui va accéder au Web Service va  fonctionner. Dans l'exemple ci-dessus, c'est la JRE (version 1.8) par défaut qui a été cochée (Use default JRE). Et ce sera également le cas pour l'application qui va utiliser le proxy.
    • Cliquer le bouton [Finish].
Au final, en suivant l'exemple ci-dessus, nous obtenons, dans l'ongle Package Explorer, un projet vide dont le nom est WSAnnuaire-Proxy :

Importation des définitions Java du Web Service

Une fois, le projet vide créé, il faut maintenant y importer la définition du Web Service à partir de l'url WSDL du Web Service à invoquer. WSDL est un langage qui permet de décrire l'interface d'un Web Service SOAP en XML. C'est-à-dire les classes, leurs propriétés et leurs méthodes des objets exposés par le Web Service qui seront exploité par l'application cliente. C'est à partir de ces définitions que les classes Java du proxy sont construites.
  • Dans Package Explorer, faire un clic droit sur le nom du projet Proxy (dans notre exemple, WSAnnuaire-Proxy).
  • Cliquer la commande New/Other...
  • Dans la fenêtre New :
    • Dans la rubrique Select a wizard, sélectionner Web Service Client.
    • Cliquer le bouton [Next >].
  • Dans la fenêtre Web Service Client :
    • Dans Service Definition, taper l'url de la définition WSDL du Web Service à invoquer (http://wsannuaire.apl/annuaire/v2.8.2/ws/annuaireService?wsdl dans l'exemple). C'est une url http ou https. 
    • Cliquer le bouton [Finish]..

Après les quelques secondes nécessaires à la génération du code Java du Proxy, on voit apparaître, dans l'onglet Package Explorer, les classes ajoutée au projet (dans le répertoire src).
A remarquer également que des bibliothèques (.jar) ont été ajoutées automatiquement dans le projet dans la rubrique Referenced libraries. Ces bibliothèques correspondent à des extensions d'Eclipse utilisées par le Proxy. Elles sont installées en standard dans la version JEE d'Eclipse. Mais elles peuvent être ajouté à la version Java standard via la commande Eclipse Marketplace du menu Help.

Création de l'application cliente

Dans l'exemple, l'application cliente sera une application fonctionnant en mode console. Mais ce peut être n'importe quelle type d'application développée en Java dans Eclipse : application graphique SWT, application Web, application Android, etc.
Il faut aussi remarquer que les opérations d'importation d'un proxy aurait pu être effectué directement dans le projet de l'application cliente. Mais il est d'une bonne pratique de le faire dans un projet à part qui, lui, peut être intégré dans le projet de l'application cliente. Ce que nous allons faire dans cet exemple. En effet, plusieurs interface différentes d'une même application, client lourd sur un poste de travail graphique (développé avec le plugin SWT), application Web ou application Mobile, qui font l'objet de projet Eclipse différents, mais qui se partagent le même Proxy pour accéder au Web Service.

Création du projet de l'application cliente

Dans cet exemple, pour faire simple, nous allons créer une application console Java qui recherche toutes les personnes enregistrées dans un annuaire à partir de son nom de famille.
La création d'une telle application est relativement simple :
  • En dessous du projet WSAnnuaire-proxy, faire un clic-droit dans Package Explorer pour lancer la commande New/Java Project.
  • Dans la fenêtre Create a Java Project :
    • Saisir le nom du projet Proxy dans Project Name (par exemple MonApplication).
    • Dans la boite JRE, choisir le même environnement JAVA dans lequel l'application qui va accéder au Web Service va  fonctionner. Dans l'exemple ci-dessus, c'est la JRE (version 1.8) par défaut qui a été cochée (Use default JRE). Il faut utiliser la même JRE que pour le Proxy.
    • Cliquer le bouton [Next >].
  • Dans la fenêtre Java Settings :
    • Choisir l'onglet Project.
    • Cliquer le bouton [Add...] dans la partie droite.
    • Dans Select projects to add, cocher la case WSAnnuaire-Proxy.
    • Cliquer le bouton [OK].
    • Cliquer l'onglet Libraries.
    • Cliquer le bouton [Add External JARs...].
    • Utiliser l'explorateur de fichier pour retrouver le fichier axis.jar. La localisation de ce fichier dépend de l'installation d'Eclipse. Cependant, il est simple d'en retrouver le chemin dans le répertoire Referenced Libraries du Proxy.
    • Cliquer le bouton [Finish].
    Au final, en suivant l'exemple ci-dessus, nous obtenons, dans l'onglet Package Explorer, un projet vide dont le nom est MonApplication et le projet WSAnnuaire-Proxy créé précédemment :

Dans la démarche précédente, les références au Proxy ont été ajoutées à l'application principale au moment de la création du projet. Mais si ce n'est pas les cas, pas de souci, elles peuvent être ajoutées postérieurement à la création du projet :
  • Dans Package Explorer, faire un clic-droit sur l'application client MonApplication pour lancer la commande Build Path/Configure Build Path...
  • Dans la fenêtre Properties  for MonApplication :
    • Choisir Java Build Path dans le menu à gauche. 
    • Dans Java Build Path, choisir l'onglet Projects.
    • Cliquer le bouton [Add...] dans la partie droite.
    • Dans Select projects to add, cocher la case WSAnnuaire-Proxy.
    • Cliquer le bouton [OK].
    • Cliquer l'onglet Libraries.
    • Cliquer le bouton [Add External JARs...].
    • Utiliser l'explorateur de fichier pour retrouver le fichier axis.jar. 
    • Cliquer le bouton [Apply and Close].
Au final, le résultat est identique à la démarche précédente.

Création de la classe de l'application cliente

La création de la classe d'une application client d'un Web Service en mode console procède des mêmes étapes qu'une application console standard :
  • Dans Package Explorer, faire un clic-droit sur le répertoire src du projet MonApplication pour lancer la commande New/Class...
  • Dans la fenêtre New Java Class :
    • Dans Package, saisir le nom du package de l'application. Un package par défaut et créé si cette zone reste vide. Cependant, une bonne pratique est de construire (en minuscules) un nom de package comme un domaine web à partir du nom de la société ou de l'auteur suivi du nom du projet, éventuellement préfixé par fr. dans le cas d'une internationalisation de l'application. Par exemple : apl.monapplication. 
    • Dans Name, saisir le nom de la classe principale de l'application. Par "principale", on veut dire la classe Java qui contient la méthode main, point d'entrée de l'application. Par convention, c'est le même nom que le projet (mais ce peut être n'importe quel nom). Ici : MonApplication.
    • Dans la rubrique Which method stubs would you like to create, cocher la case public static void main(String[] args). Cela a pour effet de créer automatiquement un squelette pour la méthode main de l'application. Mais cela peut être fait aussi manuellement dans l'éditeur Java.
    • Cliquer le bouton [Finish].
Ces opérations effectuées, nous obtenons l'affichage suivant dans Eclipse :

Codage de l'application

En tant qu'exemple, l'application fonctionne en mode console. Elle permet à un utilisateur d'effectuer une recherche sur l'annuaire à partir d'un nom saisi au clavier. L'application invoque le service de recherche du Web Service Annuaire en lui passant en paramètre le nom recherché. En retour, le service renvoie un liste de personnes dont l'application affiche le nom et le prénom.
La définition des méthodes Java du Web Service utilisées a été importé au moment de la création du projet de l'application. Et le code de ces méthodes a été généré automatiquement dans le projet Proxy.
Les instructions de programmation sont insérées entre les accolades de la fonction main :
package apl.monapplication;

/*1*/
import java.rmi.RemoteException;
import java.util.Scanner;

import fr.afpa.annuaire.ws.service.services.AnnuaireServiceProxy;
import fr.afpa.annuaire.ws.service.xsd.references.annuaire.IdentitePersonnePhysique;
import fr.afpa.annuaire.ws.service.xsd.services.AnnuaireService.RechercherPersonnesPhysiquesCommencantParRequestType;

public class MonApplication {

public static void main(String[] args) {
/*2*/
AnnuaireServiceProxy service = new AnnuaireServiceProxy();
/*3*/
RechercherPersonnesPhysiquesCommencantParRequestType request = null;
    Scanner keyboard = new Scanner(System.in); 
/*4*/
while (true) {
try {
System.out.print("Taper le nom de recherche :");
String nom = keyboard.nextLine();
if (nom.length() == 0) break;
/*5*/
request = new RechercherPersonnesPhysiquesCommencantParRequestType();
request.setNom(nom);
/*6*/
IdentitePersonnePhysique [] personnes = service.rechercherPersonnesPhysiquesCommencantPar(request);
for (IdentitePersonnePhysique personne : personnes) {
System.out.println(personne.getNomDeFamille() + " " + personne.getPrenom());
}
/*7*/
} catch (Erreur em) {
System.err.println(em.getCode() + " - " + em.getMessage1());
} catch (RemoteException re) {
System.err.println(re.getMessage());
}
}
keyboard.close();
System.out.println("Fin de la recherche !");
}
}
Voici quelques explications concernant le code ci-dessus :
  1. Les classes du Proxy utilisée doivent être importées. Dans l'IDE Eclipse, l'import est automatique, dès que l'on utilise une classe du Web Service, si le projet WSAnnuaire-Proxy a été intégré dans le Build Path de l'application.
  2. La première chose à faire pour invoquer une méthode d'un Web Service est de l’instancier. La classe AnnuaireServiceProxy est défini dans le projet WSAnnuaire-Proxy. Toutes les classes du Web Service sont définies à partir des informations fournies par l'interface WSDL.
  3. Toutes les méthodes exposées par le Web Service disposent  d'une classe de requête. Pour la méthode rechercherPersonnePhysiqueCommencantPar, il s'agit de la classe rechercherPersonnePhysiqueCommencantParRequestType. De façon générale toutes les méthodes du  Web Service disposent d'un type requête de la forme [NOM DE LA METHODE]RequestType.
  4. L'application fonctionne comme une boucle sans fin. La boucle s'arrête dès qu'un retour de chariot est effectué directement sur le prompt de recherche.
  5. Pour pouvoir invoquer une méthode d'un Web Service, un requête doit être instanciée. Cette requête permet d’initialiser les paramètres  à passer dans la méthode. Dans  cet exemple la requête de une instance de la classe rechercherPersonnePhysiqueCommencantParRequestType.  Les paramètres de la méthodes sont initialisés via le setters de la classe de la requête. Les setters de la classe rechercherPersonnePhysiqueCommencantParRequestType permettent de passer à la méthode les critères de recherche d'une personne dans l'Annuaire. Pour une recherche par nom, il suffit d’initialiser la propriété nom de la requête en utilisant le setter setNom.
  6. La méthode rechercherPersonnePhysiqueCommencantPar est alors invoquée via l'instance service du Web Service. Le paramètre request permet de passer les critères de recherche (le nom pour notre exemple). Cette méthode renvoie une collection d'objets de classe IdentitePersonnePhysique. Cette collection peut alors être itérée dans une boucle for pour afficher le nom et le prénom des personnes correspondant aux critères de recherche.
    Il faut remarquer ici que la plupart des méthodes du Web Service Annuaire renvoient un résultat de  type [[NOM DE LA METHODE]ResponseType dont les propriétés permettent de récupérer celles de l'objet métier attendu en résultat. 
  7. Toute invocation d'une méthode du Web Service doivent être effectué à l'intérieur d'un try/catch Java. En effet, ces invocations peuvent générer deux types d'exceptions :
    • des exceptions  métier (erreur dans les paramètres passés par exemple)  dont la classe définie dans le WSDL est Erreur. Dans notre exemple, nous avons fait le choix d'afficher le code (propriété code de la classe Erreur) et le message métier (propriété message1 de la classe Erreur).
    • des exceptions de type technique (erreurs de connexion sur les serveurs qui hébergent le Web Service par exemple) dont la classe est RemoteException.

Exécution du programme MonApplication

Lorsque tout est ok, il est possible de lancer l'exécution du programme :
Taper le nom de recherche :macpelt
MacPelt Lisbeth
MacPelt Johan
macPelt Johan
MacPelt Sharon
MacPelt Michael
MacPelt Michael
Taper le nom de recherche :

Quelques points d'attention

L'installation d'Eclipe peut différer en fonction  de la version de la JRE ou de la distribution utilisée. Du coup cela génère quelques messages d'erreur très difficiles à diagnostiquer qui empêche l'exécution de l'application.

Premier message

Lors du lancement de l'application, le message ci-dessous s'affiche dans la console :
mai 16, 2019 1:34:16 PM org.apache.axis.utils.JavaUtils isAttachmentSupported AVERTISSEMENT: Unable to find required classes (javax.activation.DataHandler and javax.mail.internet.MimeMultipart). Attachment support is disabled.
Ce message n'est pas bloquant. Il signale que deux librairies, activation.jar et javax.mail.jar, sont manquantes dans le projet WSAnnuaire-Proxy et n'ont pas été ajoutées au projet (pour une raison inconnue) automatiquement à l'importation WSDL comme les autres librairies.
  • Dans Package Explorer, faire un clic-droit sur le projet du Proxy client WSAnnuaire-Proxy pour lancer la commande Build Path/Configure Build Path...
  • Dans la fenêtre Properties  for WS-ANnuaire-Proxy:
    • Choisir Java Build Path dans le menu à gauche. 
    • Cliquer l'onglet Libraries.
    • Cliquer le bouton [Add External JARs...].
    • Utiliser l'explorateur de fichier pour retrouver les fichier activation.jar et javax.mail.jar. Ces deux librairies se trouvent dans la distribution de la JRE Java C:\Program Files\Java\JRExxx\lib, xxx désignant la version de la JRE (1.8.0_171 dans l'exemple).
    • Cliquer le bouton [Apply and Close].

Second Message

The type org.apache.axis.AxisFault cannot be resolved. It is indirectly referenced from required .class files

Cette erreur est signalée dans Eclipse sur les fichiers qui importent les classes du Web Service. Elle est bloquante et très difficile à diagnostiquer. Car elle apparaît dans l'éditeur Eclipse comme une erreur de syntaxe Java sur le premier caractère du fichier source (le p du mot clef package, en l’occurrence), alors que la syntaxe Java est tout à fait correcte par ailleurs.
Cette erreur est générée par l’absence de la bibliothèque axis.jar contenant la définition de la classe AxisFault de laquelle est dérivée la classe Erreur du Proxy générée au moment de l'importation WSDL et utilisée pour gérer les exceptions métier lors de l'usage des méthodes du Web Service.
  • Dans Package Explorer, faire un clic-droit sur le projet du Proxy client MonApplication pour lancer la commande Build Path/Configure Build Path...
  • Dans la fenêtre Properties  for MonApplication:
    • Choisir Java Build Path dans le menu à gauche. 
    • Cliquer l'onglet Libraries.
    • Cliquer le bouton [Add External JARs...].
    • Utiliser l'explorateur de fichier pour retrouver le fichier axis.jar. La localisation de ce fichier dépend de l'installation d'Eclipse. Cependant, il est simple d'en retrouver le chemin dans le répertoire Referenced Libraries du projet WSAnnuaire-Proxy.
    • Cliquer le bouton [Apply and Close].

Commentaires

Posts les plus consultés de ce blog

Installer WampServer