mardi, novembre 29, 2011

Tutorial Approche Contract First avec JAX-WS


DiggIt! Enregistrer sur Del.icio.us

 

Voilà plus de 4 ans (avril 2007), j’ai fait un long tutoriel sur l’approche Contract First avec Axis2 : http://jl2tho.blogspot.com/2007/04/tutorial-services-web-avec-axis2.html.

Peu après, je découvrais la norme JAX-WS pour les Services Web et réalisais un tutorial pour créer un service web pour JBoss 4.2 en utilisant JAX-WS : http://jl2tho.blogspot.com/2007/05/tutorial-service-web-avec-jbosss-42.html. On était toujours en 2007.

Plus récemment, j’ai actualisé ce dernier tutorial pour une utilisation avec JBoss 5.1 http://jl2tho.blogspot.com/2011/11/tutorial-service-web-avec-jbosss-51.html puis WebSphere 6.1 : http://jl2tho.blogspot.com/2011/11/ce-tutorial-adapte-pour-ibm-websphere-6.html. Mais ces tutoriaux JAX-WS, ne montre qu’un cas d’utilisation très simple.

Aujourd’hui, avec ce nouveau tutorial, je souhaite montrer toute la puissance de l’approche JAX-WS sur un exemple plus complet, proche de celui de mon tutoriel sur Axis2.

Avant d’aller plus loin, je vais vous présenter les étapes de ce tutorial :

  • Etape 1 : Approche Contract first (ce bilet)
    • Approche Contract First
    • JAX-WS
    • La synthèse
    • Le projet
  • Etape 2 : Configuration du projet
    • Création du projet Eclipse
    • web.xml
  • Etape 3 : Le métier
    • Objet Question
    • FaultBean et exception
    • Interface
    • Implémentation
  • Etape 4 : Annotation
    • JAX-WS : interface et implémentation
    • JAXB pour décrire l’objet question
  • Etape 5 : déploiement et WSDL
    • WSDL
    • Type simple plus compliqué
    • inclure son propre WSDL
  • Etape 6 : Injection Spring pour le métier
    • Ajout des jar Spring
    • Surcharge du bean pour activation de l’autowired

Chaque étape fera l’objet d’un billet. L’objectif de ce tutorial est de faire le tour d’un exemple suffisamment complexe pour être un cas significatif de la problématique qui sera rencontrée dans le cadre d’un véritable développement.

Si vous êtes débutant sur JAX-WS, je vous encourage à suivre au préalable mon tutorial d’introduction à JAX-WS avec JBoss 5.1 : http://jl2tho.blogspot.com/2011/11/tutorial-service-web-avec-jbosss-51.html. Ce tutorial présente les concepts et mécanismes de base sur lesquels je vais m’appuyer sans pour autant les reprendre de manière détaillée dans ce tutorial.

Dans la suite de ce billet, je développe les raisons de mon choix et de mon approche.

Approche Contract First : Avantages et inconvénients

Dans l’absolu, l’approche Contract First consiste à définir le contrat qui va lier le consommateur du service web avec son fournisseur. Dans la norme Web Service, ce contrat est le WSDL. Il s’agit d’un fichier XML qui décrit le format des messages XML qui seront échangés entre le client et le service.

Sa structure est normée mais sa lecture et compréhension sont peu aisées ou du moins fastidieuses. Dans mon tutorial Axis2 http://jl2tho.blogspot.com/2007/04/tutorial-services-web-avec-axis2.html, je présente un outil permettant d’écrire ce fichier WSDL

Pour moi, cette approche Contract First est intéressante car elle permet de dégager le contrat des implémentations technologiques du service : les types simples ne dépendent pas du langage choisi, on augmente ses chances que le service que l’on va produire puisse être réutilisé par des clients dans des technologies différentes.

En revanche, la solution retenue est longue et fastidieuse : il faut définir des messages ainsi que tous les champs constitutifs un à un.

D’autre part, la solution Axis2 utilisée, n’offrait pas à l’époque, un modèle de développement très efficace : mon code d’appel du service sans passer par la couche Service Web diffère trop (à mon gout) de l’appel du même service en direct. Cela me dérange, car je pense aux cas de tests jUnit que je pourrais plus facilement réutiliser avec une approche dans laquelle les deux interfaces seraient plus proches.

JAX-WS

Très rapidement après cette première expérience Axis2, j’ai découvert JAX-WS. Il s’agit d’un élément de la norme des EJB 3.0 sur laquelle elle s’appuie.

Ce qui m’a plu dans l’approche JAX-WS est son efficacité au niveau du développement : on ne multiplie pas les fichiers de configuration grâce aux annotations. Mais surtout, on ne manipule plus la structure des fichiers XML (les messages) que l’on soit sur le client ou le serveur.

La vision du développement du service ou du client utilisateur du service est celle d’un simple appel d’une méthode possédant des paramètres : on ne peut faire plus simple.

Les différents tutoriaux que j’ai réalisé sur cette approche, montre bien cette simplicité :

Ils montrent également la puissance de la norme, car au delà des différences de configuration de l’environnement de développement et du déploiement, le développement est identique. Si on retient l’approche WAR utilisée pour WebSphere, le même binaire (WAR) peut être déployé sur les différents serveurs d’application sans modification.

Dès 2007, nous avons opté pour l’approche JAX-WS au niveau de tous nos développements en remplacement de la solution Axis (version 1) que nous utilisions jusqu’à présent. Cela montre l’intérêt que j’ai eu pour cette approche.

JAX-WS et l’approche Contract First

Je vais certainement choquer quelques extrémistes, mais je souhaitais concilier les deux approches : utiliser les annotations JAX-WS pour définir mon contrat : le fichier WSDL.

JAX-WS fonctionnant par annotation d’une classe Java représentant de fait du code, il peut paraitre contradictoire de parler d’approche Contract First : j’écris du code Java avant le WSDL.

Néanmoins, en premier lieu, je me limite à la déclaration de mon interface et une implémentation vide : je n’ai que des prototypes de classe : parler de code est un peu excessif à ce niveau. De plus, je décris en Java le service que je veux offrir plus que son implémentation qui reste vide à cette étape.

Je vais ensuite annoter ces classes et interfaces par itération jusqu’à obtenir le WSDL qui me convient. Ce n’est qu’ensuite que je commence à coder l’implémentation du métier.

De mon point de vu, au lieu d’utiliser un outil graphique comme celui que j’ai utilisé avec Axis2, pour définir le WSDL, j’utilise le langage Java et les annotations JAX-WS. Je considère cette approche doublement plus efficace :

  1. elle est plus naturelle : on commence par décrire le prototype d’un service.
  2. j’ai eu l’impression d’avoir une plus grande maitrise du WSDL produit avec les annotations JAX-WS qu’avec l’outil graphique

Cela ne fonctionne que parce que JAX-WS produit un WSDL technologiquement neutre : les types simples ne sont pas Java. Je n’ai pas eu à faire des efforts démesurés pour utiliser des types basics.

Un dernier avantage et un petit inconvénient (les deux sont liés) :

  • Il est possible d’avoir une démarche agile avec cette approche : je peux travailler sur le WSDL en adaptant les annotations tout en avançant sur l’implémentation du service à chaque run.
  • On peut avoir tendance à passer aux développements trop rapidement (avant d’avoir fini la partie WSDL) et/ou à réutiliser des objets provenant du développement dans les prototypes des méthodes de service. Cela peut être problématique car l’objet peut avoir une complexité ou une structure inadaptée au service souhaité.

Projet du tutorial

Notre mini projet consistera à rendre disponible un service de consultation des Questions soumise à un Helpdesk (on reprend la thématique du projet Axis2).

Nous allons créer 3 services qui manipulent un objet Question en paramètre :

  • rechercher une question à partir de son ID (validation d’un format en entrée 9 caractères numériques)
  • créer une question : retourne un ID de question (objet complexe en entrée, un format date, une énumération, un entier compris en 0 et 4 pour l’urgence)
  • récupérer une liste de questions avec une énumération en entrée (liste d’objets en sortie et énumération)

J’ai recherché à tester les aspects suivants :

  • Manipulation d’objets métier structurés
  • Typage fort des données : au delà du simple type (entier, string…) spécifier la taille limite, des plages de valeurs…
  • Manipulation de liste d’objets structurés

Il s’agit des mêmes objectifs que ceux que j’avais adopté lors de mon tutoriel Axis 2 : Approche Contract First.

Afin de rester dans une approche Contract First malgré l’utilisation de JAX-WS, l’implémentation réelle des services ne sera abordé qu’en dernier lieu avec l’injection de bean Spring.

Toutes les étapes préliminaires vont servir à définir le plus précisément le WSDL du service en utilisant :

  • les annotations JAX-WS
  • les annotations JAXB : il s’agit d’une norme sœur de JAX-WS permettant de décrire comment un objet Java est transformé en XML.
  • l’utilisation d’une exception particulière afin de définir précisément les messages d’erreur retournés par le service
  • la surcharge du WSDL produit afin de compléter les déclarations de type

Ce n’est qu’une fois le WSDL validé que l’on se penchera sur la récupération des ressources configurées (DAO, Factory Hibernate…) nécessaires à l’implémentation du service. C’est à ce moment que Spring sera introduit.

 

J’ai fini de présenter les objectifs de ce tutorial, nous allons passer dans le billet suivant dans le vif du sujet : la configuration du projet (étape 2 du tutorial).

Etapes : 1 | 2 | 3 | 4 | 5 –  Suivant >


DiggIt! Enregistrer sur Del.icio.us

0 commentaires: