IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Tutoriel sur le développement de services web étendus avec JAX-WS, Maven et Eclipse

L'objectif de cette deuxième série d'exercices est d'apprendre à manipuler l'API JAX-WS pour le développement de services web étendus à partir de la plateforme de développement Java.

Chaque exercice est fourni avec un projet Java Maven contenant des classes et des fichiers de configuration qu'il faudra compléter au fur et à mesure des questions. À la fin de chaque exercice, une solution du projet Java sera donnée.

Buts pédagogiques : transformation d'un POJO Java en service web, génération des artifacts à partir d'une description WSDL, utilisation de l'outillage fourni depuis JavaSE 6, mise en place d'un intercepteur (handler), clients service web en mode synchrone et asynchrone, outils wsgen et wsimport.

Les codes pour les exercices sont disponibles sur le dépôt Git suivant : https://github.com/mickaelbaron/jaxws-tutorial (pour récupérer le code faire : $ git clone https://github.com/mickaelbaron/jaxws-tutorial).

La solution de tous les exercices est disponible sur la branche solution : $ git checkout solution

Pour réagir au contenu de ce tutoriel, un espace de dialogue vous est proposé sur le forum 21 commentaires Donner une note à l´article (5).

Article lu   fois.

L'auteur

Profil ProSite personnel

Liens sociaux

Viadeo Twitter Facebook Share on Google+   

Prérequis logiciels

Avant de démarrer cette série d'exercices sur l'utilisation de l'API JAX-WS, veuillez préparer votre environnement de développement en installant les outils suivants

I. Exercice 1 : Développer un service web suivant une approche montante « Bottom/Up »

I-A. But

  • Décrire un service web à partir d'une interface Java.
  • Implémenter le service web.
  • Publier en local et tester le service web via SOAP-UI.

I-B. Description

Le service web de ce premier exercice consiste à fournir des opérations pour la gestion d'un carnet d'adresses simplifié. Une opération pour ajouter une personne, une autre pour récupérer la liste complète et enfin une dernière opération pour récupérer une personne par un nom. Une personne est décrite par un nom (String) et une adresse (String).

I-C. Étapes à suivre

  • Démarrer l'environnement de développement Eclipse.
  • Importer le projet Maven jaxws-tutorial-exercice1 (File -> Import -> Maven -> Existing Maven Projects, choisir le répertoire du projet puis faire Finish.
  • Depuis le package fr.mickaelbaron.jaxwstutorialexercice1, créer une classe qui représentera une personne (File -> New puis choisir Class). Appeler la classe Person et la définir dans le package fr.mickaelbaron.jaxwstutorialexercice1.
  • Dans la nouvelle classe créée, ajouter un attribut name de type String et un attribut address de type String. Définir un constructeur par défaut (important pour JAXB) et un constructeur avec deux paramètres correspondant respectivement à l'initialisation des deux attributs. Générer via l'éditeur les modificateurs et les accesseurs. Pour la génération, exploiter les outils fournis par Eclipse (Source… -> Generate Getters and Setters via le menu contextuel de la classe Java).
 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
package fr.mickaelbaron.jaxwstutorialexercice1;

public class Person {

    private String name;

    private String address;

    public Person() {
    }

    public Person(String name, String address) {
        this.name = name;
        this.address = address;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }
}
  • Définir une interface Java représentant la description du service web (File -> New puis choisir Interface). Définir comme nom de l'interface NotebookService et utiliser le précédent package.
  • Ajouter les méthodes suivantes dans l'interface NotebookService :

    • boolean addPerson(Person p) : ajouter une nouvelle personne ;
    • List<Person> getPersons() : récupérer toutes les personnes ;
    • Person getPersonAt(String name) : récupérer une personne par son nom.
  • Ajouter une annotation @WebService au niveau de l'interface puis initialiser ces attributs name à NotebookService et targetNamespace à http://jaxwstutorialexercice1.mickaelbaron.fr.
 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
package fr.mickaelbaron.jaxwstutorialexercice1;

import java.util.List;
import javax.jws.WebService;

// TODO: définir l'interface en service web SOAP
// en initialisant les attributs `name` et `targetNamespace`.
public interface NotebookService {

    boolean addPerson(Person p);

    List<Person> getPersons();

    Person getPersonAt(String name);
}
 
Cacher/Afficher le codeSélectionnez
  • Construire une nouvelle classe appelée NotebookServiceImpl qui implémente l'interface NotebookService.
  • Ajouter une annotation @WebService au niveau de la classe, puis modifier les attributs de l'annotation comme décrit ci-dessous :

    • endpointInterface = fr.mickaelbaron.jaxwstutorialexercice1.NotebookService;
    • serviceName = NotebookService ;
    • portName = NotebookPort.
  • Ci-dessous est donné un exemple d'implémentation de la classe NotebookServiceImpl. Saisir le code de la classe NotebookServiceImpl. Le corps des méthodes n'est pas très important.
 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
package fr.mickaelbaron.jaxwstutorialexercice1;

import java.util.ArrayList;
import java.util.List;

import javax.jws.WebService;

// TODO: définir la classe en service web SOAP
// en initialisant les attributs `endpointInterface`, `serviceName` et `portName`.
public class NotebookServiceImpl implements NotebookService {

    private List<Person> persons = new ArrayList<Person>();

    public NotebookServiceImpl() {
        persons.add(new Person("Mickael Baron", "Migné-Auxances"));
        persons.add(new Person("Sébastien Loeb", "France"));
    }

    @Override
    public boolean addPerson(Person p) {
        System.out.println("addPerson method has been invoked:" + p);

        if (p == null) throw new NullPointerException("Person is null");

        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        return persons.add(p);
    }

    @Override
    public List<Person> getPersons() {
        System.out.println("getPersons method has been invoked.");

        return persons;
    }

    @Override
    public Person getPersonAt(String name) {
        System.out.println("getPersonAt method has been invoked: " + name);

        if (name == null || name.isEmpty()) throw new NullPointerException("Name is null.");

        for (Person person : persons) {
            if (name.equals(person.getName())) return person;
        }
        return null;
    }
}
 
Cacher/Afficher le codeSélectionnez
  • Afin de tester localement ce service web, définir une classe appelée NotebookWebServicePublisher à déposer dans le package déjà créé et saisir le code ci-dessous.
 
Sélectionnez
1.
2.
3.
4.
5.
public class NotebookWebServicePublisher {
    public static void main(String[] args) throws ClassNotFoundException {
        Endpoint.publish("http://localhost:9991/ws/notebookservice", new NotebookServiceImpl());
    }
}
  • Exécuter la classe NotebookWebServicePublisher pour démarrer votre service web. Selon la version de Java que vous utilisez, différents messages d'avertissement seront affichés.

Pour tester le comportement du service web, vous utiliserez l'outil SOAP-UI (voir atelier 1atelier 1).

Nous allons nous intéresser à générer le document WSDL à partir de Maven.

  • Depuis Eclipse, exécuter la configuration d'exécution appelée wsgen1 (clean and process-classes).
  • Depuis la ligne de commande, se placer à la racine du projet et exécuter la ligne de commande suivante :
 
Sélectionnez
mvn clean package
  • Vérifier depuis le répertoire target/generated-sources/wsdl la présence du document WSDL.
  • Déterminer dans le fichier pom.xml, le plugin qui permet de générer automatiquement le contrat WSDL.

II. Exercice 2 : Développer un service web suivant une approche descendante « Top/Down »

II-A. But

  • Générer les artifacts d'un service web à partir d'une description WSDL.
  • Implémenter le service web.
  • Publier en local.
  • Tester le service web.
  • Utilisation de wsimport.

II-B. Description

Dans cet exercice, nous développons un service web à partir de sa description WSDL. Pour cela, nous nous basons sur la description WSDL du service web obtenue à la fin de l'exercice 1. L'intérêt est de montrer que 1) la génération des classes (artifacts) ne donne pas exactement les mêmes classes que celles construites dans l'exercice 1 et 2) la génération est obligatoire.

II-C. Étapes à suivre

  • Assurez-vous que le programme principal du premier exercice est en cours d'exécution et que le WSDL du service web est toujours accessible.
  • Importer le projet Maven jaxws-tutorial-exercice2 (File -> Import -> Maven -> Existing Maven Projects, choisir le répertoire du projet puis faire Finish.
  • Afin de générer les classes (artifacts), nous utilisons l'outil wsimport par l'intermédiaire de Maven. Compléter le fichier de description Maven pom.xml existant.
 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
<plugin>
    <groupId>com.sun.xml.ws</groupId>
    <artifactId>jaxws-maven-plugin</artifactId>
    <version>${jaxws.version}</version>
    <executions>
        <execution>
            <goals>
                <goal>wsimport</goal>
            </goals>
            <configuration>
                <packageName>fr.mickaelbaron.jaxwstutorialexercice2</packageName>
                <sourceDestDir>${project.build.directory}/generated-sources/jaxws-wsimport</sourceDestDir>
                <keep>true</keep>
                <wsdlUrls>
                    <wsdlUrl>http://localhost:9991/ws/notebookservice?wsdl</wsdlUrl>
                </wsdlUrls>
            </configuration>
        </execution>
    </executions>
</plugin>
  • Depuis Eclipse, exécuter la configuration d'exécution appelée wsimport2 (clean and generate-sources). Si vous rencontrez des soucis avec l'intégration Maven sous Eclipse, exécuter la commande shell suivante à la racine de votre projet $ mvn clean generate-sources. Un ensemble de classes sera généré par l'outil wsimport et localisé dans le répertoire ./target/generated-sources/jaxws-wsimport. Ces classes ne doivent pas être modifiées puisqu'elles sont générées automatiquement.

Il reste maintenant à implémenter la classe NotebookServiceImpl. Elle correspond à la classe implémentant le comportement du service web.

  • Réutiliser et adapter le code de l'exercice 1 pour compléter cette classe.

III. Exercice 3 : Développer un client de service web en mode synchrone

III-A. But

  • Développer un client d'un service web.
  • Appel synchrone de service web.
  • Outil wsimport et test d'intégration.

III-B. Description

Cet exercice consiste à appeler le service web défini depuis l'exercice 1. Des tests unitaires ont été définis pour invoquer les différentes méthodes.

III-C. Étapes à suivre

  • Assurez-vous que le programme principal de l'exercice 1 est en cours d'exécution et que le WSDL du service web est toujours accessible.
  • jaxws-tutorial-exercice3 (File -> Import -> Maven -> Existing Maven Projects, choisir le répertoire du projet puis faire Finish.
  • Compléter le fichier de description Maven pom.xml existant afin de générer les classes artifacts.
 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
<<plugin>
    <groupId>com.sun.xml.ws</groupId>
    <artifactId>jaxws-maven-plugin</artifactId>
    <version>${jaxws.version}</version>
    <executions>
        <execution>
            <goals>
                <goal>wsimport</goal>
            </goals>
            <configuration>
                <packageName>fr.mickaelbaron.jaxwstutorialexercice3</packageName>
                <sourceDestDir>${project.build.directory}/generated-sources/jaxws-wsimport</sourceDestDir>
                <keep>true</keep>
                <wsdlUrls>
                    <wsdlUrl>http://localhost:9991/ws/notebookservice?wsdl</wsdlUrl>
                </wsdlUrls>
            </configuration>
        </execution>
    </executions>
</plugin>
  • Depuis Eclipse, exécuter la configuration d'exécution appelée wsimport3 (clean and generate-sources). Si vous rencontrez des soucis avec l'intégration Maven sous Eclipse, exécuter la ligne de commande suivante à la racine de votre projet $ mvn clean generate-sources. Un ensemble de classes sera généré par l'outil wsimport et localisé dans le répertoire ./target/generated-sources/jaxws-wsimport. Ces classes ne doivent pas être modifiées puisqu'elles sont générées automatiquement.
  • Compléter la classe de test NotebookWebServiceTest afin d'accéder au port du service puis exécuter les tests unitaires.
 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
package fr.mickaelbaron.jaxwstutorialexercice3;

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

public class NotebookWebServiceTest {

    protected NotebookService notebookPort;

    @Before
    public void setup() {
        NotebookService_Service notebookService = new NotebookService_Service();
        notebookPort = notebookService.getNotebookPort();
    }

    @Test
    public void addPersonTest() {
        // Given
        Person myPerson = new Person();
        myPerson.setName("NewPerson");
        myPerson.setAddress("NewAddress");

        // When
        // TODO: appeler l'opération `addPerson`.

        // Then
        Assert.assertTrue(addPerson);
    }

    @Test
    public void getPersonsTest() {
        // Given
        // When
        // TODO: appeler l'opération `getPersons`.

        // Then
        Assert.assertTrue(persons.size() >= 2);
    }

    @Test
    public void getPersonAtTest() {
        // Given
        // TODO: initialiser une variable à 'Mickael Baron'.

        // When
        // TODO: appeler l'opération `getPersonAt` avec la variable précédente.

        // Then
        Assert.assertNotNull(personAt);
        Assert.assertEquals(personAt.getAddress(), "Migné-Auxances");
    }
}
 
Cacher/Afficher le codeSélectionnez

IV. Exercice 4 : développer un client de service web en mode asynchrone

IV-A. But

  • Développer un client d'un service web.
  • Appel asynchrone de service web.
  • Outil wsimport.
  • Client lourd via une interface graphique SWING.

IV-B. Description

Cet exercice consiste à appeler le service web défini dans l'exercice 1. Un client lourd défini via une interface graphique SWING est utilisé pour invoquer l'opération addPerson(...) en mode asynchrone. L'intérêt de cet exercice est de montrer comment paramétrer la génération des artifacts via wsimport pour le mode asynchrone.

IV-C. Étapes à suivre

  • Assurez-vous que le programme principal du premier exercice est en cours d'exécution et que le WSDL du service web est toujours accessible.
  • jaxws-tutorial-exercice4 (File -> Import -> Maven -> Existing Maven Projects, choisir le répertoire du projet puis faire Finish.
  • Pour modifier la génération des classes artifacts des informations supplémentaires peuvent être indiquées dans un fichier binding. Créer un fichier nommé binding.xml stocké dans le répertoire src/jaxws dont le contenu est le suivant.
 
Sélectionnez
1.
2.
3.
4.
5.
6.
<?xml version="1.0" encoding="UTF-8"?>
<bindings
    wsdlLocation="http://localhost:9991/ws/NotebookService?wsdl"
    xmlns="http://java.sun.com/xml/ns/jaxws">
    <enableAsyncMapping>true</enableAsyncMapping>
</bindings>
  • Compléter le fichier de description Maven pom.xml existant afin de générer les classes artifacts (identique à l'exercice 2 et 3). Pour la prise en compte du fichier binding.xml vous ajouterez ces paramètres dans le contenu de la balise configuration.
 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
<configuration>
    ...
    <bindingFiles>
        <bindingFile>
            ${basedir}/src/main/resources/binding.xml
        </bindingFile>
    </bindingFiles>
</configuration>
  • Depuis Eclipse, exécuter la configuration d'exécution appelée wsimport (clean and generate-sources) comme pour les exercices 2 et 3.
  • Compléter la classe NotebookWebServiceAsynchronousClient
 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
package fr.mickaelbaron.jaxwstutorialexercice4;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.xml.ws.AsyncHandler;
import javax.xml.ws.Response;

public class NotebookWebServiceAsynchronousClient extends JFrame {

    private static final long serialVersionUID = -8095150953761740313L;

    public NotebookWebServiceAsynchronousClient() {
        super("NotebookWebServiceAsynchronous Client");

        this.setLayout(new BorderLayout());
        final JButton startButton = new JButton("Call addPerson operation");
        this.getContentPane().add(BorderLayout.NORTH, startButton);

        final JTextArea textArea = new JTextArea();
        textArea.setEditable(false);
        this.getContentPane().add(BorderLayout.CENTER, textArea);

        startButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                startButton.setEnabled(false);
                Person newPerson = new Person();
                newPerson.setName("New Person");
                newPerson.setAddress("Poitiers");

                textArea.append("addPerson operation has been invoked.\n");

                // TODO: initialiser un service et un port.

                // TODO: invoquer de manière asynchrone l'opération `addPerson` à partir du port précédent
                // et faire appel au code suivant.
                //     if (!res.isCancelled() && res.isDone()) {
                //         textArea.append("New Person added.\n");
                //         startButton.setEnabled(true);
                //     }
            }
        });

        this.pack();
        this.setVisible(true);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    public static void main(String[] args) {
        new NotebookWebServiceAsynchronousClient();
    }
}
 
Cacher/Afficher le codeSélectionnez
  • Exécuter le programme, le résultat attendu est celui montré sur la figure ci-dessous.
Swing exercice 4

V. Exercice 5 : Ajouter un intercepteur (handler) à un service web

V-A. But

  • Implémentation handler côté serveur.
  • Configuration du service web.
  • Filtrage par opération.
  • Développer un client d'un service web.

V-B. Description

Dans cet exercice un intercepteur est ajouté au service web décrivant le carnet d'adresses. L'intercepteur a pour fonction de filtrer les messages SOAP de telle sorte que le traitement de l'opération getPersons() ne soit pas réalisé.

V-C. Étapes à suivre

  • jaxws-tutorial-exercice5 (File -> Import -> Maven -> Existing Maven Projects, choisir le répertoire du projet puis faire Finish.
  • Dans la classe NotebookServiceImpl, ajouter l'annotation @HandlerChain(file = "handler.xml") au niveau de la description de la classe.
  • Ajouter un fichier handler.xml, au niveau du répertoire src/main/resources.
 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
<?xml version="1.0" encoding="UTF-8"?>
<handler-chains xmlns="http://java.sun.com/xml/ns/javaee">
    <handler-chain>
       <handler>
           <handler-name>fr.mickaelbaron.jaxwstutorialexercice5.SOAPLoggingHandler</handler-name>
           <handler-class>fr.mickaelbaron.jaxwstutorialexercice5.SOAPLoggingHandler</handler-class>
       </handler>
    </handler-chain>
</handler-chains>
  • Ajouter une nouvelle classe intitulée SOAPLoggingHandler dont le code est défini de la manière suivante.
 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
package fr.mickaelbaron.jaxwstutorialexercice5;

import java.util.Set;

import javax.xml.namespace.QName;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPException;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;

public class SOAPLoggingHandler implements SOAPHandler<SOAPMessageContext> {

    @Override
    public Set<QName> getHeaders() {
        return null;
    }

    @Override
    public void close(MessageContext context) {
    }

    @Override
    public boolean handleMessage(SOAPMessageContext smc) {
        Boolean outboundProperty = (Boolean) smc
                .get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);

        if (outboundProperty.booleanValue()) {
            return false;
        } else {
            String methodName = getMethodName(smc, true);
            if (!"getPersons".equals(methodName)) {
                System.out.println(methodName + ": authorized");
                return true;
            } else {
                System.out.println(methodName + ": not authorized");
                return false;
            }
        }
    }

    @Override
    public boolean handleFault(SOAPMessageContext smc) {
        return true;
    }

    private String getMethodName(SOAPMessageContext context, boolean isRequest) {
        try {
            SOAPEnvelope envelope = context.getMessage().getSOAPPart().getEnvelope();
            SOAPBody body = envelope.getBody();
            return body.getChildNodes().item(0).getLocalName();
        } catch (SOAPException e) {
            e.printStackTrace();

            return null;
        }
    }
}
  • Exécuter la classe NotebookWebServicePublisher pour démarrer votre service web.
  • À partir de l'outil SOAP-UI (voir atelier 1), vérifier que l'appel à l'opération getPersons retourne une réponse vide.

VI. Exercice 6 : déployer des services web étendus

VI-A. But

  • Déployer pour des tests.
  • Packager un service web dans une archive War.
  • Déployer un service web sur le serveur d'applications Java Tomcat.
  • Gérer les problèmes de dépendances.

VI-B. Description

Dans cet exercice nous allons réaliser deux types de déploiement d'un service web étendu : un déploiement pour des tests (exécuter depuis un jar) et un déploiement sur le serveur d'applications Tomcat (déployer un fichier war). Nous ferons abstraction de l'environnement de développement Eclipse afin d'être le plus proche de l'environnement de production.

VI-C. Étapes à suivre pour effectuer un déploiement pour des tests (utilisation de la classe Endpoint)

Remarquez que le contenu des fichiers Java est identique au projet jaxws-tutorial-exercice1.

  • Saisir la ligne de commande suivante pour démarrer le projet.
 
Sélectionnez
$ java -cp "target/ws.jar" fr.mickaelbaron.jaxwstutorialexercice6.NotebookWebServicePublisher
Exception in thread "main" java.lang.NoClassDefFoundError: javax/xml/ws/Endpoint
        at fr.mickaelbaron.jaxwstutorialexercice6.NotebookWebServicePublisher.main(NotebookWebServicePublisher.java:10)
Caused by: java.lang.ClassNotFoundException: javax.xml.ws.Endpoint
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:582)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:190)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:499)
    ... 1 more

Vous remarquerez que le projet de démarre pas du fait de l'absence de certaines dépendances. Il est donc nécessaire de fournir lors de l'exécution (dans le classpath) les dépendances nécessaires.

  • Modifier le fichier pom.xml afin d'ajouter le plugin maven-dependency-plugin qui permettra de lister toutes les bibliothèques nécessaires.
 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <version>${maven.dependency.version}</version>
                <executions>
                    <execution>
                        <id>copy-dependencies</id>
                        <phase>package</phase>
                        <goals>
                            <goal>copy-dependencies</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
  • Saisir les lignes de commande suivantes pour compiler, construire et démarrer le projet.
 
Sélectionnez
$ mvn clean package
...
$ java -cp "target/classes:target/dependency/*" fr.mickaelbaron.jaxwstutorialexercice6.NotebookWebServicePublisher

VIII-D. Étapes à suivre pour effectuer un déploiement sur le serveur d'applications Tomcat

Le fichier web.xml est utilisé pour configurer le déploiement de l'application web. Ainsi pour accéder à l'application vous devrez utiliser le contexte suivant /notebookservice.

  • Compléter le fichier web.xml à partir de la configuration donnée ci-dessous.
 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
<web-app>
    <display-name>jaxws-tutorial-exercice6</display-name>
    <listener>
        <listener-class>com.sun.xml.ws.transport.http.servlet.WSServletContextListener</listener-class>
    </listener>
    <servlet>
        <display-name>notebookservice</display-name>
        <servlet-name>notebookservice</servlet-name>
        <servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>notebookservice</servlet-name>
        <url-pattern>/notebookservice</url-pattern>
    </servlet-mapping>
    <session-config>
        <session-timeout>60</session-timeout>
    </session-config>
</web-app>

Le fichier sun-jaxws.xml est utilisé pour configurer l'accès au service web SOAP. Il permet de mapper le contexte /notebookservice avec la classe qui implémente le service web étendue NotebookServiceImpl.

  • Compléter le fichier à partir de la configuration donnée ci-dessous.
 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
<?xml version="1.0" encoding="UTF-8"?>

<endpoints xmlns='http://java.sun.com/xml/ns/jax-ws/ri/runtime' version='2.0'>
    <endpoint
        name='notebookservice'
        implementation='fr.mickaelbaron.jaxwstutorialexercice6.NotebookServiceImpl'
        url-pattern='/notebookservice'/>
</endpoints>
  • Saisir la ligne de commande suivante pour compiler et construire le projet vers un fichier war.
 
Sélectionnez
mvn clean package -P war

Le fichier web.xml est utilisé pour configurer l'application web. Ainsi pour accéder à l'application vous devrez utiliser le contexte suivant /notebookwebservice.

  • Compléter le fichier à partir de la configuration donnée ci-dessous.
 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
...
<web-app>
    <display-name>NotebookWebService6</display-name>
    <listener>
        <listener-class>com.sun.xml.ws.transport.http.servlet.WSServletContextListener</listener-class>
    </listener>
    <servlet>
        <display-name>notebookwebservice6</display-name>
        <servlet-name>notebookwebservice6</servlet-name>
        <servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>notebookwebservice6</servlet-name>
        <url-pattern>/notebookwebservice6</url-pattern>
    </servlet-mapping>
    <session-config>
        <session-timeout>60</session-timeout>
    </session-config>
</web-app>

Le fichier sun-jaxws.xml est utilisé pour configurer l'accès au service web SOAP. Ainsi pour accéder au service web le chemin relatif à utiliser sera /notebookwebservice6/notebookwebservice.

  • Compléter le fichier à partir de la configuration donnée ci-dessous.
 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
<?xml version="1.0" encoding="UTF-8"?>

<endpoints xmlns='http://java.sun.com/xml/ns/jax-ws/ri/runtime' version='2.0'>
    <endpoint
        name='notebookservice'
        implementation='fr.mickaelbaron.jaxwstutorialexercice6.NotebookServiceImpl'
        url-pattern='/notebookservice'/>
</endpoints>
  • Saisir la ligne de commande suivante pour compiler et construire le projet vers un fichier war.
 
Sélectionnez
mvn clean package -P war

L'option -P war permet d'utiliser le profile Maven appelé war. Depuis le fichier pom.xml examiner la balise <profiles>. Cette astuce permet de générer un fichier jar ou un fichier war depuis un même fichier pom.xml.

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
    ...
    <packaging>${project.packaging}</packaging>
    ...
    <profiles>
        <profile>
            <id>jar</id>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
            <properties>
                <project.packaging>jar</project.packaging>
            </properties>
        </profile>
        <profile>
            <id>war</id>
            <properties>
                <project.packaging>war</project.packaging>
            </properties>
        </profile>
    </profiles>
  • Saisir la ligne de commande suivante pour télécharger une image Docker de Tomcat
 
Sélectionnez
docker pull tomcat:9.0.12-jre10-slim
  • Enfin, saisir la ligne de commande suivante pour créer un conteneur Docker qui permettra de démarrer une instance de Tomcat. Le fichier `ws.war` contient tous le code et dépendances de ce projet.
 
Sélectionnez
docker run --rm --name helloworldservice-tomcat -v $(pwd)/target/ws.war:/usr/local/tomcat/webapps/ws.war -it -p 8080:8080 tomcat:9.0.12-jre10-slim

VII. Conclusion et remerciements

Nous avons vu au travers de six exercices comment utiliser l'API JAX-WS. Nous avons notamment insisté sur le développement de services web et de clients utilisés pour appeler les services web de type étendu.

Pour aller plus loin, vous pouvez consulter les ressources suivantes :

Vous pouvez retrouver cette série d'exercices sur mon compte Github : https://github.com/mickaelbaron/jaxws-tutorialApprendre à manipuler l'API JAX-WS pour le développement de services web étendus à partir de la plateforme de développement Java.

Je tiens à remercier Claude Leloup pour sa relecture orthographique de cet article.

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2016 Mickael Baron. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.