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).
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.
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);
}
- 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.
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
;
}
}
- 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.
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.
- Afficher la description WSDL de votre service web http://localhost:9991/ws/notebookservice?wsdl et comparer le résultat par rapport à ce qui a été défini dans l'interface Java.
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 :
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.
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.
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.
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"
);
}
}
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.
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.
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
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 =
-
8095150953761740313
L;
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
(
);
}
}
- Exécuter le programme, le résultat attendu est celui montré sur la figure ci-dessous.
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.
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.
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.
$
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.
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.
$
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.
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.
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.
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.
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.
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.
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.
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
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.
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
- Ouvrir un navigateur web et tester l'URL suivante : http://localhost:8080/ws/notebookservice?wsdl et visualiser le WSDL.
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 :
- Support de cours SOASupport de cours SOA
- Support de cours WSDLSupport de cours WSDL
- Support de cours SOAPSupport de cours SOAP
- Support de cours JAX-WSSupport de cours JAX-WS
- Exercices sur le test fonctionnel de services web avec SOAP-UIExercices sur le test fonctionnel de services web avec SOAP-UI
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.