Archive

Archive for the ‘Java’ Category

WebService "Contract First" avec Spring-WS

Contract First vs Code First

La méthode la plus répandue pour exposer des WebServices en Java est la méthode dite « Code First » : on développe un composant Java et on s’appuie ensuite sur un outil pour exposer ce composant sous forme de WebService. Cet outil va analyser les signatures des méthodes de votre composant et va générer un descripteur de WebService : le WSDL. Le développeur jette ensuite un oeil (ou pas) à ce descripteur et se félicite de ne pas avoir eu à écrire ce fichier très verbeux.

Un autre développeur récupère le fameux descripteur WSDL et utilise un autre langage ou un autre outil pour générer le code client et c’est la que les choses se compliquent souvent.

Je vais prendre comme exemple un service de recherche dans un annuaire, ce service permet de rechercher des personnes à partir de leur nom, prénom et ville de résidence. Deux critères sont obligatoires : le nom et la ville de résidence.

Voici l’interface Java qui correspond au service :

@WebService
public interface AnnuaireService {
	List<Personne> rechercher(String nom, String prenom, String ville);
}

Une fois ce service déployé à l’aide de la pile de WebService CXF, le WSDL généré déclare le type suivant pour représenter le message de recherche :

<xs:complexType name="rechercher">
	<xs:sequence>
		<xs:element minOccurs="0" name="arg0" type="xs:string" />
		<xs:element minOccurs="0" name="arg1" type="xs:string" />
		<xs:element minOccurs="0" name="arg2" type="xs:string" />
	</xs:sequence>
</xs:complexType>

Cette déclaration n’est pas utilisable dans l’état, les critères de recherche ne sont pas nommés et tous les critères sont marqués comme optionnels (minOccurs=0).
Il est donc necessaire d’annoter l’interface Java pour permettre à CXF de générer un WSDL plus significatif.

@WebService
public interface AnnuaireService {
	List<Personne> rechercher(
		@WebParam(name="nom") String nom,
		@WebParam(name="prenom") String prenom,
		@WebParam(name="ville") String ville);
}

Les critères de recherche sont maintenant nommés dans le WSDL :

<xs:complexType name="rechercher">
	<xs:sequence>
		<xs:element minOccurs="0" name="nom" type="xs:string" />
		<xs:element minOccurs="0" name="prenom" type="xs:string" />
		<xs:element minOccurs="0" name="ville" type="xs:string" />
	</xs:sequence>
</xs:complexType>

La spécification JAX-WS ne permet pas de rendre les paramètres obligatoires.

Il existe bien sur des solutions de contournement pour que le WSDL soit plus conforme au contrat du service, mais cet exemple trivial nous montre que la génération du WSDL à partir du code Java necessite d’enrichir le code avec des méta données et que le résultat ne permet pas d’utiliser le WSDL généré comme contrat solide entre le producteur et les consommateurs.

Pour que le WSDL reprenne son rôle de contrat, il est important qu’il spécifie le plus précisément possible les messages d’entrée et de sortie du WebService. La démarche « Contract First » met justement l’accent sur la contractualisation des messages échangés.

Contract First avec Spring WS

Le descripteur WSDL reste très verbeux et la perspective de gérer ces fichiers à la main est assez effrayante. Rassurez vous, nous allons nous contenter de décrire les messages en entrée et sortie à l’aide de XML Schema (XSD).
Une fois ces messages décrits, nous allons nous appuyer sur JAXB et Spring-WS pour implémenter le contrat.

Voici le schéma décrivant le message de recherche dans l’annuaire :

<element name="rechercherRequest">
	<complexType>
		<annotation>
			<documentation>
				Message d'entrée pour la recherche dans l'annuaire
   		</documentation>
		</annotation>
		<sequence>
			<element name="nom" type="string" />
			<element name="prenom" type="string" minOccurs="0" />
			<element name="ville" type="string" />
		</sequence>
	</complexType>
</element>

Une configuration rapide de la génération des objets Java à partir du XML Schema à l’aide de maven 2 :

<plugin>
	<groupId>org.codehaus.mojo</groupId>
	<artifactId>jaxb2-maven-plugin</artifactId>
	<version>1.3</version>
	<executions>
		<execution>
			<goals>
				<goal>xjc</goal>
			</goals>
		</execution>
	</executions>
</plugin>

Et voici l’objet qui correspond à la requête :

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "nom",
    "prenom",
    "ville"
})
@XmlRootElement(name = "rechercherRequest")
public class RechercherRequest {

    @XmlElement(required = true)
    protected String nom;
    protected String prenom;
    @XmlElement(required = true)
    protected String ville;
 ....
 

Certes c’est verbeux mais c’est du codé généré donc pas de couts d’intégration ou de maintenance.

Voici maintenant la signature du composant Java qui prend en charge la requête :

@Endpoint
public class AnnuaireEndpoint {
	@PayloadRoot(localPart = "rechercherRequest", namespace = "http://yellowpages.tartachuc.org")
	public RechercherResponse rechercher(RechercherRequest request) {

....

Une première annotation @Endpoint marque la classe et la rend detectable par le « component-scan » de spring. La seconde annotation @PayloadRoot indique quel message est traité par la méthode.

Cette mise en oeuvre de Spring-WS permet d’assurer un contrat WSDL soigné tout en ne pénalisant pas la productivité des développements. Dernier avantage, cette démarche impose de concevoir les messages échangés ce qui favorisera des messages plus expressifs et simples  qui facilitent l’utilisation des services tout en évitant d’exposer directement les objets « privés ».

Publicités
Étiquettes : ,

ChtiJUG : Session Hibernate chez Norsys

Le 21 Septembre, le ChtiJUG organise une session animée par Emmanuel Bernard qui travaille pour JBoss sur Hibernate et plus particulièrement sur Hibernate Search et Hibernate Validation.

C’est Norsys qui accueille cette session dans nos locaux de Ennevelin.

Dépêchez vous de vous inscrire, les places sont réservées à vitesse grand V.

Étiquettes :

GWT : Démonstration du mode OOPHM

Sami Jaber a publié une vidéo de démonstration du mode OOPHM de GWT 2.0.

OOPHM est l’acronyme de « Out Of Process Hosted Mode », ce mode va permettre d’exécuter le mode Hosted dans un navigateur classique simplement équipé d’un plugin pour communiquer avec la JVM.

Étiquettes :

Outillage pour GWT

En ce moment je travaille sur des tests de performance d’une application GWT.

Comme d’habitude au petit déjeuner je consulte mon newsreader et je tombe sur cette annonce de l’équipe Google.

Le Debug Panel permet d’analyser finement les performances d’une application GWT vu du client. A commencer par de lancement de l’application : temps passé à télécharger les scripts, temps passé dans le onModuleLoad.

bootstrap

Cet outil permet également de écomposer les appels de services RPC : temps de sérialisation , temps passé à poster les donnés vers le serveur, temps de receptin des données en retour, temps de désérialisation et durée de mise à jour de l’interface.

service

Il y a des journées qui commencent moins bien 🙂

Étiquettes :

GWT : Fonctionalités et Roadmap

Étiquettes :

Maven2 au ChtiJUG

Ce soir j’ai participé à la deuxième réunion du ChtiJUG, le club des Javaistes du Nord.

Thème de la soirée : Maven2, la présentation était effectuée par Arnaud Héritier, commiter et membre du comité du projet.

Cela fait maintenant 6 ans que je pratique Maven et je venais surtout pour profiter de l’expérience d’Arnaud que l’on imagine avoir participé à de multiples mises en places.

J’ai trouvé la présentation intéressante, Arnaud ne manie pas la langue de bois et n’est pas avar en anecdotes et conseils.

Voici les points que j’ai retenu de sa présentation :

  • Maven ne convient pas à tous les projets, notamment quand il n’y a pas de besoin de standardisation ou de réutilisation
  • Dans un premier temps, se contenter d’une mise en place simpliste, en évitant de sur utiliser les capacités avancées de l’outil : héritages à n niveaux, trop de modules, profils, …
  • De concentrer ensuite sur la sécurisation du build : utiliser un proxy maven pour pallier à une défaillance des serveurs centraux, préciser la version de tous les plugins.
  • Enfin : industrialiser le build : mettre en place une intégration continue, mettre en place les outils et rapports qualité, automatiser la release.

Arnaud a également pas mal partagé sur sa vision des outils de l’écosystème Maven et se montre très enthousiaste quand il parle de Nexus (proxy et référentiel maven)  ou de Hudson (intégration continue)

Autre remarque d’Arnaud : configurez Maven pour qu’il s’adapte à votre IDE et pas l’inverse : il faut passer le moins de temps possible dans la console.

Je pense que la fin de la présentation ainsi que certaines questions ont du plonger une bonne partie de la salle dans de profonds doutes quand au coté simple de l’outil, le niveau était assez relevé 🙂

Coup de chapeau à mon ami et collègue Jérémy qui a brillamment gagné une licence IntelliJ IDEA en répondant à une question difficile : de quel projet est issu Maven : vous le saviez vous ?

Étiquettes : ,

Sortie de Sonar 1.6

9 février 2009 1 commentaire

Le blog du projet Sonar annonce la sortie de la version 1.6 de ce très bon outil de suivi qualité.

Voici une liste des nouveautés :

  • Paramétrages des règles au sein de profils, ces profils contiennent tous les paramètres et sont entièrement exportables.
  • Possibilité de définir des seuils d’alerte, au sein des profils. Cela permet de matérialiser le respect des objectifs de qualité du projet par une icône en fonction de son état.
    Pour chaque alerte, on peut définir un seuil de « orange » et un seuil « rouge ». Un flux Atom permet de s’abonner à ces alertes.
  • Et enfin, la grosse nouveauté de mon point de vue, la possibilité d’affecter un profil différent à chaque projet et donc d’adapter les règles au contexte et aux choix de chaque équipe.

A noter que la mise à jour se fait sans difficulté.

Étiquettes : ,