vendredi 5 octobre 2007

Tutoriel JAX-WS - Partie II (Développement)

Voici la seconde partie de la série "Tutoriel JAX-WS". Celle-ci est consacrée au développement à proprement parlé du Web Service. On va commencer par importer un WSDL d'exemple. Par la suite, on va générer du code avec les outils de JAX-WS. Enfin, on terminera par l'implémentation du service à proprement parler.

Import du WSDL

La configuration n'es pas complètement terminée mais on peut commencer à coder notre Web Service. Dans notre cas d'école, on va prendre un WSDL fourni avec les samples de Metro, plus précisément, le fichier samples/fromwsdl/etc/AddNumbers.wsdl. Nous allons importer ce fichier dans le répertoire src du projet. La copie d'écran suivante montre à quoi doit ressembler votre eclipse à ce stade :

Génération de code

Nous allons maintenant générer le code du service et des "artifacts" associées à partir du fichier WSDL. Je n'ai pas trouvé de plugin Eclipse pour Metro ou JAX-WS alors on va utiliser directement l'outil fourni avec l'implémentation JAX-WS (dans le Jar webservices-tools.jar). Pour cela, on va lancer l'utilitaire WSImport à partir d'eclipse.

A partir du menu Run/Open Run Dialog..., on va créer un nouveau "lanceur" de type Java Application. Vous pouvez lui donner un joli petit nom histoire de pouvoir le reconnaître par la suite. Ensuite, dans l'encart Main class et à l'aide du bouton Search, vous allez utiliser la classe com.sun.tools.ws.WsImport qui correspond à l'outil de génération de code. Vous devez avoir quelque chose du genre :


Il faut passer des infos à cet outil, notamment le fichier WSDL à prendre en entrée et lui dire à quel endroit mettre les fichiers générés. Toutes ces options sont documentées sur le site de JAX-WS. Attention, si vous avez des espaces dans les noms de répertoire (je pense aux personnes sous Windows avec le C:\Documents and Settings par exemple), veillez à mettre entre "" les options ...

Si vous utilisez le JDK 6+, vous allez être confronté à un problème de conflit de version entre l'API JAX-WS intégrée au JDK (version 2.0) et celle utilisée par Metro (Version 2.1). Le symptôme est le suivant :

You are running on JDK6 which comes with JAX-WS 2.0 API, but this tool requires JAX-WS 2.1 API. Use the endorsed standards override mechanism (http://java.sun.com/javase/6/docs/technotes/guides/standards/), or use -Xendorsed option.

Pour résoudre ce problème, il faut indiquer à la JVM où trouver la bonne version avec le mécanisme suggéré par le message d'erreur. Le screenhot suivant montre, en plus des options de génération de code, l'argument à passer à la JVM (les Jar jaxws-api.jar et jaxb-api.jar suffisent) :

Voici une explication rapide des options utilisées :

  • -wsdllocation : JAX-WS utilise le WSDL au "runtime" et cette balise permet de mettre une annotation JAX-WS pour spécifier où trouver le WSDL. Dans notre exemple, c'est pour le retrouver dans notre projet dans le package par défaut. Par défaut, l'URL ou le chemin utilisé pour la génération de code est utilisé. Ne voulant pas mettre une dépendance avec ce lien dans mon code, je spécifie cette option.
  • -verbose : Permet d'afficher ce que fait l'outil dans la console.
  • -s : Donne le répertoire où mettre le code généré.
Cliquez sur le bouton Run et faîtes un Refresh sur votre projet. Les sources vont alors apparaître dans votre projet. Il ne nous reste plus qu'à implémenter notre classe de service. Une classe peut être supprimée, celle du client, à savoir AddNumbersService.

Implémentation du service

Une interface a été générée (org.example.duke.AddNumbersPortType). Nous allons l'implémenter. Pour cela, on créé une classe org.example.duke.AddNumbersServiceImpl qui implémente cette interface. On rajoute la décoration JAX-WS pour exposer cette classe sous forme de Web Service à l'aide de l'annotation @WebService avec en paramètre l'interface exposée : @WebService(endpointInterface="org.example.duke.AddNumbersPortType").
Il reste à ajouter du code dans nos méthodes et nous aurons terminé l'implémentation. Voici ce que cela peut donner :


Note : J'ai rencontré dans certain cas, des erreurs de compilation d'eclipse que je n'ai pas su expliquer. En redémarrant Eclipse, aidé d'un petit "clean", j'ai résolu le problème mais cela n'est quand même pas très "clean' ...

Nous avons terminé l'implémentation du service. Il reste maintenant à déployer notre Web Service sous Tomcat à l'aide de Metro. Ceci fera l'objet de la 3ème partie du tutoriel ...

7 commentaires:

Anonyme a dit…

merci pour ton tutoriel par contre j'ai un problème : au moment de la génération de code, tu préviens de mettre les "" pour les windowsiens, je vois pas où il faut les mettre. A aucun moment je ne passe comme adresse C:\Documents and Settings pourtant j'ai cette erreur : directory not found: C:\Documents. J'écris exactement la même chose que toi dans Program arguments.

Laurent a dit…

En fait, les "${workspace_loc:...}" sont des chaînes qui sont remplacés par Eclipse pour mettre à la place le chemin du workspace utilisé.
Ton workspace doit probablement être sous C:\Documents and Settings ...
Au final, les arguments doivent ressembler à quelque chose du genre :
-verbose -wsdllocation AddNumbers.wsdl -s "${workspace_loc:testMetro/src}" "${workspace_loc:testMetro/src}/AddNumbers.wsdl}"

pierre a dit…

Merci pour ta réponse rapide. Effectivement le code que tu as mis arrive à s'exécuter mais rencontre un autre problème. Apparemment le fichier wsdl est inaccessible :
parsing WSDL...


[ERROR] file:/C:/Documents%20and%20Settings/pierre/Bureau /workspace/testMetro/src/AddNumbers.wsdl} is unreachable


Failed to parse the WSDL.

Pourtant le AddNumbers.wsdl est bien dans ce dossier. As tu une idée pour résoudre ce problème?

Laurent a dit…

Je pense qu'il y a un "}" en trop à la fin. Dans ma réponse d'hier, j'en ai mis un en trop à la fin. Tu as peut-être fait un copier/coller et du coup récupérer le caractère en trop ?

pierre a dit…

Le vieux copier coller ^^. Merci pour ton aide et pour ton tuto.

Anonyme a dit…

Bonjour,

J'ai suivi le tuto et arrivé à la génération des sources, aucune erreur mais aucune source créée non plus!^^ Pourtant j'ai le même wsdl de metro.
Une idée?

merci.

Anonyme a dit…

Trouvé! Faut que j'apprenne à lire. Les paramètres définissant le workspace, je ne les avais pas mis entre guillemets.
Je pensais que les "" ne servaient qu'aux adresses complètes(ex: C:\documents and settings\...) et non aux relatives (${workspace_loc:...}).

Merci