jeudi 27 septembre 2012

Services Web avec Apache CXF et Spring 3


Aujourd’hui je vous présente un exemple d’une application web qui publie un Service Web simple à l'aide d’Apache CXF et Spring sur un serveur léger (Tomcat) pour un test rapide.
Pour commencer ce test on a besoin des outils suivant : 

  1. Maven 3
  2. Spring 3.1.1
  3. Apache CXF 2.6.0
  4. Tomcat 7


Voici l’architecture du projet : 




Étape 1 : création du service web 

AfficherHoraireService (Interface)
Afin de travailler avec les services Web, il faut utiliser des interfaces pour nos services ...

AfficherHoraireServiceImpl (Implémentation)
Le paramètre endpointInterface doit pointer vers l'interface que nous mettons en œuvre pour le service Web…

Étape 2 : intégration Spring / CXF 
 
Parmis les avantages du framework CXF est sa bonne intégration avec le framework Spring et que le code généré est beaucoup, beaucoup plus petit qu’avec les autres...
service-definition-beans.xml
‹?xml version="1.0" encoding="UTF-8"?› 
‹beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns="http://www.springframework.org/schema/beans"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"/

    ‹bean id="afficherHoraireService"
          class="com.saou.demo.services.AfficherHoraireServiceImpl" /
  
/beans
Ici, nous définissons un bean service normal (afficherHoraireService).

webservice-definition-beans.xml
‹?xml version="1.0" encoding="UTF-8"?› 
‹beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns="http://www.springframework.org/schema/beans"
    xmlns:jaxws="http://cxf.apache.org/jaxws"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
  http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
  http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd"/

    ‹import resource="classpath:service-definition-beans.xml" /

    ‹jaxws:endpoint id="afficherHoraireWebService"
          implementor="#afficherHoraireService"
          address="/AfficherHoraire" /
  
/beans
Vous voudrez peut-être séparés les fichiers xml de définition des beans, plutôt il est important de les séparer par fonctionnalité (par exemple : les beans service, les beans webservice, les beans test...). En fait le bean afficherHoraireService défini dans le service-definition-beans.xml peut être déplacé ici au lieu d'importer cette ressource. Avec #afficherHoraireService nous faisons référence à un bean avec id="afficherHoraireService"...

Ajoutez au fichier web.xml les éléments permettant de charger le conteneur spring.
!DOCTYPE web-app PUBLIC
  "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
  "http://java.sun.com/dtd/web-app_2_3.dtd" 

‹web-app
   ‹context-param
       ‹param-namecontextConfigLocation‹/param-name  
       ‹param-valueWEB-INF/webservice-definition-beans.xml‹/param-value  
   ‹/context-param 
    
   ‹listener
       ‹listener-class  
           org.springframework.web.context.ContextLoaderListener
       ‹/display-name  
   ‹/listener 

   ‹servlet
       ‹servlet-nameCXFServlet‹/servlet-name  
       ‹display-nameCXF Servlet‹/display-name
       servlet-class  
           org.apache.cxf.transport.servlet.CXFServlet
       ‹/servlet-class 
       ‹load-on-startup1‹/load-on-startup  
   ‹/servlet 

   ‹servlet-mapping
       ‹servlet-nameCXFServlet‹/servlet-name  
       ‹url-pattern/*‹/url-pattern  
   ‹/servlet-mapping 

‹web-app
C'est ici que nous configurons CXFServlet pour analyser tous notre demande sur les service Web.

Étape 3 : build maven

pom.xml
‹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"/
    ‹modelVersion4.0.0‹/modelVersion
    ‹groupIdcom.saou.demo‹/groupId
    ‹artifactIdspring-cxf-demo‹/artifactId
    ‹packagingwar‹/packaging
    ‹version1.0-SNAPSHOT‹/version
    ‹namespring-cxf-demo Maven Webapp‹/name
    ‹urlhttp://maven.apache.org‹/url

    ‹dependencies       ‹!-- Spring dependencies --
       ‹dependency
          ‹groupIdorg.springframework‹/groupId  
          ‹artifactIdspring-web‹/artifactId 
          ‹version3.1.1.RELEASE‹/version  
          ‹scopecompile‹/scope  
       ‹/dependency 
       ‹dependency
          ‹groupIdorg.springframework‹/groupId  
          ‹artifactIdspring-context‹/artifactId 
          ‹version3.1.1.RELEASE‹/version  
          ‹scopecompile‹/scope  
       ‹/dependency 

       ‹!-- Apache CXF for webservices --
       ‹dependency
          ‹groupIdorg.apache.cxf‹/groupId  
          ‹artifactIdcxf-api‹/artifactId 
          ‹version2.6.0‹/version  
          ‹scopecompile‹/scope  
       ‹/dependency 
       ‹dependency
          ‹groupIdorg.apache.cxf‹/groupId  
          ‹artifactIdcxf-rt-frontend-jaxws‹/artifactId 
          ‹version2.6.0‹/version  
          ‹scopecompile‹/scope  
       ‹/dependency 
       ‹dependency
          ‹groupIdorg.apache.cxf‹/groupId  
          ‹artifactIdcxf-rt-transports-http‹/artifactId 
          ‹version2.6.0‹/version  
          ‹scopecompile‹/scope  
       ‹/dependency 

       ‹!-- For testing purposes --
       ‹dependency
          ‹groupIdorg.springframework‹/groupId  
          ‹artifactIdspring-test‹/artifactId 
          ‹version3.1.1.RELEASE‹/version  
          ‹scopetest‹/scope  
       ‹/dependency 
       ‹dependency
          ‹groupIdjunit‹/groupId  
          ‹artifactIdjunit‹/artifactId 
          ‹version4.8.2‹/version  
          ‹scopetest‹/scope  
       ‹/dependency 
    ‹dependencies

    ‹build
       ‹finalNamejunit‹/finalName 
       ‹plugins
       ‹!-- use JDK 1.6 --
          ‹plugin
              ‹groupIdorg.apache.maven.plugins‹/groupId  
              ‹artifactIdmaven-compiler-plugin‹/artifactId 
              ‹version2.3.2‹/version  
              ‹configuration 
                  ‹source1.6‹/source  
                  ‹target1.6‹/target 
                  ‹encodingUTF-8‹/encoding  
              ‹/configuration
          ‹/plugin
       plugins
    ‹/build
/project

Maintenant il suffit de lancer la commande suivante :  mvn clean package
Après quelques secondes durant lesquels maven rapatrie en local les dépendences du projet, vous obtenez le résultat suivant :


Étape 4 : déploiement de l'application

Lancez tomcat et déposez la livraison (spring-cxf-demo.war) dans le répertoire webapps de tomcat.
Aller sur le navigateur, et tapez à l’adresse suivant : http://127.0.0.1:8080/spring-cxf-demo/

Voila CXF nous informe qu’un service web a été publié et est disponible

Étape 5 : Appel aux web services

client-definition-beans.xml
‹?xml version="1.0" encoding="UTF-8"?› 
‹beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns="http://www.springframework.org/schema/beans"
    xmlns:jaxws="http://cxf.apache.org/jaxws"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
  http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
  http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd"/

    ‹import resource="classpath:service-definition-beans.xml" /

    ‹jaxws:endpoint id="afficherHoraireWebService"
          serviceClass="com.saou.demo.services.AfficherHoraireService"
          address="/AfficherHoraire" /
  
/beans

Ici, nous créons le client webservice CXF que nous allons invoquer lors de notre test sur la classe ClientServicesWeb.

ClientServicesWeb (Test)
Lancer la commande suivante :  
mvn exec:java -Dexec.mainClass=com.saou.demo.client.ClientServicesWeb
Et voila, l'appel aux web services en mode console :


Conclusionde :
Il me faudra des raisons très convaincantes pour utiliser un autre framework car
  • Le code généré est beaucoup, beaucoup plus petit avec CXF qu’avec les autres.
  • Le code à écrire pour utiliser le framework est beaucoup plus simple et joli avec CXF.
  • CXF est plus long à s’initialiser, mais va plus vite après.

Aucun commentaire:

Enregistrer un commentaire