Services Web dans Java SE, Partie 2: Création de services Web SOAP

JAX-WS prend en charge les services Web SOAP. La partie 2 de cette série en quatre parties sur les services Web Java SE définit un service Web de conversion d'unités basé sur SOAP, construit puis vérifie ce service Web localement via le serveur HTTP léger par défaut (décrit dans la partie 1), interprète le document WSDL du service , et accède au service à partir d'un simple client.

Définition d'un service Web de conversion d'unités

Le service Web de conversion d'unités, que j'ai nommé UC, comprend quatre fonctions de conversion entre les centimètres et les pouces et entre les degrés Fahrenheit et les degrés Celsius. Bien que cet exemple puisse être conçu comme une classe Java unique, j'ai choisi de suivre les meilleures pratiques en le concevant comme une interface Java et une classe Java. Le listing 1 présente l' UCinterface du service Web .

Liste 1. Interface de point de terminaison de service du service Web UC

package ca.javajeff.uc; import javax.jws.WebMethod; import javax.jws.WebService; @WebService public interface UC { @WebMethod double c2f(double degrees); @WebMethod double cm2in(double cm); @WebMethod double f2c(double degrees); @WebMethod double in2cm(double in); }

UCdécrit une interface de point de terminaison de service (SEI) , qui est une interface Java qui expose les opérations d'une interface de service Web en termes de méthodes Java abstraites. Les clients communiquent avec les services Web SOAP via leurs SEI.

UCest déclaré comme SEI via l' @WebServiceannotation. Lorsqu'une interface ou une classe Java est annotée @WebService, toutes les publicméthodes dont les paramètres, les valeurs de retour et les exceptions déclarées suivent les règles définies dans la section 5 de la spécification JAX-RPC 1.1 décrivent les opérations de service Web. Parce que seules les publicméthodes peuvent être déclarées dans les interfaces, le publicmot réservé n'est pas nécessaire lors de la déclaration c2f(), cm2in(), f2c()et in2cm(). Ces méthodes sont implicitement public.

Chaque méthode est également annotée @WebMethod. Bien que cela @WebMethodne soit pas essentiel dans cet exemple, sa présence renforce le fait que la méthode annotée expose une opération de service Web.

Le listing 2 présente la UCImplclasse du service Web .

Listing 2. Le Bean d'implémentation de service du service Web UC

package ca.javajeff.uc; import javax.jws.WebService; @WebService(endpointInterface = "ca.javajeff.uc.UC") public class UCImpl implements UC { @Override public double c2f(double degrees) { return degrees * 9.0 / 5.0 + 32; } @Override public double cm2in(double cm) { return cm / 2.54; } @Override public double f2c(double degrees) { return (degrees - 32) * 5.0 / 9.0; } @Override public double in2cm(double in) { return in * 2.54; } }

UCImpldécrit un Bean d'implémentation de service (SIB) , qui fournit une implémentation du SEI. Cette classe est déclarée SIB via l' @WebService(endpointInterface = "ca.javajeff.uc.UC")annotation. L' endpointInterfaceélément connecte ce SIB à son SEI, et est nécessaire pour éviter les erreurs de type de port non défini lors de l'exécution de l'application client présentée plus tard.

La implements UCclause n'est pas absolument nécessaire. Si cette clause n'est pas présente, l' UCinterface est ignorée (et est redondante). Cependant, c'est une bonne idée de conserver implements UCafin que le compilateur puisse vérifier que les méthodes de SEI ont été implémentées dans le SIB.

Les en-têtes de méthode du SIB ne sont pas annotés @WebMethodcar cette annotation est généralement utilisée dans le contexte du SEI. Cependant, si vous deviez ajouter une publicméthode (qui est conforme aux règles de la section 5 de la spécification JAX-RPC 1.1) au SIB, et si cette méthode n'expose pas d'opération de service Web, vous annoterez l'en-tête de la méthode @WebMethod(exclude = true). En attribuant trueà @WebMethoddes » excludel'élément, cette méthode vous empêcher d'être associée à une opération.

Ce service Web est prêt à être publié afin d'être accessible depuis les clients. Le listing 3 présente une UCPublisherapplication qui accomplit cette tâche dans le contexte du serveur HTTP léger par défaut.

Listing 3. Publication d'UC

import javax.xml.ws.Endpoint; import ca.javajeff.uc.UCImpl; public class UCPublisher { public static void main(String[] args) { Endpoint.publish("//localhost:9901/UC", new UCImpl()); } }

La publication du service Web implique de faire un seul appel à la méthode de EndPointclasse de la Endpoint publish(String address, Object implementor)classe. Le addressparamètre identifie l'URI attribué au service Web. J'ai choisi de publier ce service Web sur l'hôte local en spécifiant localhost(équivalent à l'adresse IP 127.0.0.1) et le numéro de port 9901(qui est probablement disponible). De plus, j'ai choisi arbitrairement /UCcomme chemin de publication. Le implementorparamètre identifie une instance du UCSIB de.

La publish()méthode crée et publie un point de terminaison pour l' implementorobjet spécifié à la date donnée addresset utilise les implementorannotations de pour créer des documents WSDL (Web Services Definition Language) et XML Schema. Cela entraîne la création et la configuration de l'infrastructure de serveur nécessaire par l'implémentation JAX-WS en fonction d'une configuration par défaut. En outre, cette méthode entraîne l'exécution de l'application indéfiniment. (Sur les machines Windows, appuyez simultanément sur les touches Ctrl et C pour mettre fin à l'application.)

Création et vérification du service Web

Il n'est pas difficile de créer le service Web UC précédemment défini. Tout d'abord, vous devez créer une structure de répertoires appropriée contenant les fichiers appropriés. Accomplissez cette tâche en effectuant les étapes suivantes:

  1. Dans le répertoire courant, créez un carépertoire. À l'intérieur ca, créez un javajeffrépertoire. Enfin, à l'intérieur javajeff, créez un ucrépertoire.
  2. Copiez le listing 1 dans un UC.javafichier source et stockez ce fichier au format ca/javajeff/uc.
  3. Copiez le listing 2 dans un UCImpl.javafichier source et stockez ce fichier au format ca/javajeff/uc.
  4. Copiez le listing 3 dans un UCPublisher.javafichier source et stockez ce fichier dans le répertoire courant, qui contient le carépertoire.

La tâche suivante consiste à compiler ces fichiers source. En supposant que vous n'avez pas changé de répertoire, exécutez la commande suivante pour compiler ces fichiers source dans Java SE 9 (omettre --add-modules java.xml.wsdans Java SE 6, 7 ou 8):

javac --add-modules java.xml.ws UCPublisher.java

Si ces fichiers source se compilent correctement, exécutez la commande suivante pour exécuter cette application dans Java 9 (omettez --add-modules java.xml.wsdans Java SE 6, 7 ou 8):

java --add-modules java.xml.ws UCPublisher

Pendant l'exécution de l'application, utilisez un navigateur Web pour vérifier que ce service Web s'exécute correctement et pour accéder à son document WSDL. Démarrez votre navigateur Web préféré et entrez la ligne suivante dans la barre d'adresse:

//localhost:9901/UC

La figure 1 montre la page Web résultante dans le navigateur Web Google Chrome.

Figure 1. La page Web d'UC fournit des informations détaillées sur le service Web publié

La figure 1 présente les noms de service et de port qualifiés du point de terminaison de service Web. (Notez que le nom du package a été inversé - uc.javajeff.caau lieu de ca.javajeff.uc). Un client utilise ces noms pour accéder au service.

La figure 1 présente également l'adresse URI du service Web, l'emplacement du document WSDL du service Web (l'URI du service Web suffixée par la ?wsdlchaîne de requête) et le nom qualifié du package de la classe d'implémentation du service Web.

Interprétation du document WSDL du service Web

L'emplacement du document WSDL du service Web UC est présenté sous forme de lien. Cliquez sur ce lien pour afficher le document WSDL, dont le contenu est présenté dans le Listing 4.

Listing 4. Document WSDL d'UC

Un document WSDL est un document XML avec un definitionsélément racine, ce qui fait d'un document WSDL rien de plus qu'un ensemble de définitions. Cet élément comprend divers xmlnsattributs pour identifier divers espaces de noms standard, ainsi que des attributs targetNameSpaceet name:

  • L' targetNamespaceattribut crée un espace de noms pour tous les éléments définis par l'utilisateur dans le document WSDL (tels que l' c2félément défini via l' messageélément portant ce nom). Cet espace de noms est utilisé pour faire la distinction entre les éléments définis par l'utilisateur du document WSDL actuel et les éléments définis par l'utilisateur des documents WSDL importés, qui sont identifiés via l' importélément WSDL . De la même manière, l' targetNamespaceattribut qui apparaît sur l' schemaélément d'un fichier basé sur un schéma XML crée un espace de noms pour ses éléments de type simple définis par l'utilisateur, ses éléments d'attribut et ses éléments de type complexe.
  • L' nameattribut identifie le service Web et est utilisé uniquement pour documenter le service.

Emboîtés dans definitionssont types, message, portType, binding, et serviceéléments: