Introduction à JAX-WS

1. Vue d’ensemble

Java L’API pour les services Web XML (JAX-WS) est une API normalisée permettant de créer et de consommer des services Web SOAP (Simple Object Access Protocol).

Dans cet article, nous allons créer un service Web SOAP et nous y connecter via JAX-WS.

2. SAVON

SOAP est une spécification XML permettant d’envoyer des messages sur un réseau.

SOAP est lourd en XML, il est donc préférable de l’utiliser avec des outils/frameworks. JAX-WS est un framework qui simplifie l’utilisation de SOAP. Cela fait partie de Java standard.

3. De haut en bas et de bas en haut

Il existe deux manières de créer des services Web SOAP. Nous pouvons opter pour une approche descendante ou ascendante.

Dans une approche top-down (contrat d’abord), un document WSDL est créé et les classes Java nécessaires sont générées à partir du WSDL. Dans une approche ascendante (dernier contrat),

D’autre part, puisque votre WSDL est généré à partir des classes Java, toute modification de code peut entraîner une modification du WSDL. Ce n’est pas le cas pour l’approche descendante.

4. Langage de définition de services Web (WSDL)

WSDL est une définition du contrat des services disponibles. Il s’agit d’une spécification de messages d’entrée/sortie et de la procédure à suivre pour appeler le service Web. Il est indépendant du langage et défini en XML.

Examinons les principaux éléments d’un document WSDL.

4.1. Définitions

L’élément definitions est l’élément racine de tous les documents WSDL. Il définit le nom, l’espace de noms, etc. du service et, comme vous pouvez le constater, peut être assez spacieux:

<definitions xmlns="http://schemas.xmlsoap.org/wsdl/"
  xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
  xmlns:tns="http://jaxws.baeldung.com/"
  xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata"
  xmlns:wsp="http://www.w3.org/ns/ws-policy"
  xmlns:wsp1__2="http://schemas.xmlsoap.org/ws/2004/09/policy"
  xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  targetNamespace="http://jaxws.baeldung.com/"
  name="EmployeeService">
  ...
</definitions>

4.2. Les types

L’élément types définit les types de données utilisés par le service Web. WSDL utilise XSD (définition de schéma XML) comme système de types facilitant l’interopérabilité:

<definitions ...>
    ...
    <types>
        <xsd:schema>
            <xsd:import namespace="http://jaxws.baeldung.com/"
              schemaLocation = "http://localhost:8080/employeeservice?xsd=1"/>
        </xsd:schema>
    </types>
    ...
</definitions>

4.3. Messages

L’élément message fournit une définition abstraite des données en cours de transmission. Chaque élément message décrit l’entrée ou la sortie d’une méthode de service et les exceptions possibles:

<definitions ...>
    ...
    <message name="getEmployee">
        <part name="parameters" element="tns:getEmployee"/>
    </message>
    <message name="getEmployeeResponse">
        <part name="parameters" element="tns:getEmployeeResponse"/>
    </message>
    <message name="EmployeeNotFound">
        <part name="fault" element="tns:EmployeeNotFound"/>
    </message>
    ...
</definitions>

4.4. Opérations et types de ports

L’élément portType décrit chaque opération pouvant être effectuée et tous les éléments message impliqués. Par exemple, l’opération getEmployee spécifie la requête input , output et l’éventuelle exception fault levée par le service Web operation :

<definitions ...>
    ...
    <portType name="EmployeeService">
        <operation name="getEmployee">
            <input
              wsam:Action="http://jaxws.baeldung.com/EmployeeService/getEmployeeRequest"
              message="tns:getEmployee"/>
            <output
              wsam:Action="http://jaxws.baeldung.com/EmployeeService/getEmployeeResponse"
              message="tns:getEmployeeResponse"/>
            <fault message="tns:EmployeeNotFound" name="EmployeeNotFound"
              wsam:Action="http://jaxws.baeldung.com/EmployeeService/getEmployee/Fault/EmployeeNotFound"/>
        </operation>
    ....
    </portType>
    ...
</definitions>

4.5. Reliures

L’élément binding fournit les détails du protocole et du format de données pour chaque portType :

<definitions ...>
    ...
    <binding name="EmployeeServiceImplPortBinding"
      type="tns:EmployeeService">
        <soap:binding transport="http://schemas.xmlsoap.org/soap/http"
          style="document"/>
        <operation name="getEmployee">
            <soap:operation soapAction=""/>
            <input>
                <soap:body use="literal"/>
            </input>
            <output>
                <soap:body use="literal"/>
            </output>
            <fault name="EmployeeNotFound">
                <soap:fault name="EmployeeNotFound" use="literal"/>
            </fault>
        </operation>
        ...
    </binding>
    ...
</definitions>

4.6. Services et Ports

L’élément service définit les ports pris en charge par le service Web.

L’élément port dans service définit les noms name , binding et address du service:

<definitions ...>
    ...
    <service name="EmployeeService">
        <port name="EmployeeServiceImplPort"
          binding="tns:EmployeeServiceImplPortBinding">
            <soap:address
              location="http://localhost:8080/employeeservice"/>
        </port>
    </service>
    ...
</definitions>

5. Approche descendante (contrat d’abord)

Commençons par une approche descendante en créant un fichier WSDL employeeservicetopdown.wsdl. Par souci de simplicité, il n’existe qu’une méthode:

<?xml version="1.0" encoding="UTF-8"?>
<definitions
  xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
  xmlns:tns="http://topdown.server.jaxws.baeldung.com/"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns="http://schemas.xmlsoap.org/wsdl/"
  targetNamespace="http://topdown.server.jaxws.baeldung.com/"
  qname="EmployeeServiceTopDown">
    <types>
        <xsd:schema
          targetNamespace="http://topdown.server.jaxws.baeldung.com/">
            <xsd:element name="countEmployeesResponse" type="xsd:int"/>
        </xsd:schema>
    </types>

    <message name="countEmployees">
    </message>
    <message name="countEmployeesResponse">
        <part name="parameters" element="tns:countEmployeesResponse"/>
    </message>
    <portType name="EmployeeServiceTopDown">
        <operation name="countEmployees">
            <input message="tns:countEmployees"/>
            <output message="tns:countEmployeesResponse"/>
        </operation>
    </portType>
    <binding name="EmployeeServiceTopDownSOAP"
      type="tns:EmployeeServiceTopDown">
        <soap:binding transport="http://schemas.xmlsoap.org/soap/http"
          style="document"/>
        <operation name="countEmployees">
            <soap:operation
              soapAction="http://topdown.server.jaxws.baeldung.com/              EmployeeServiceTopDown/countEmployees"/>
            <input>
                <soap:body use="literal"/>
            </input>
            <output>
                <soap:body use="literal"/>
            </output>
        </operation>
    </binding>
    <service name="EmployeeServiceTopDown">
        <port name="EmployeeServiceTopDownSOAP"
          binding="tns:EmployeeServiceTopDownSOAP">
            <soap:address
              location="http://localhost:8080/employeeservicetopdown"/>
        </port>
    </service>
</definitions>

5.1. Génération des fichiers source de service Web à partir de WSDL

Pour générer des fichiers source de service Web à partir d’un document WSDL, nous pouvons utiliser l’outil wsimport , qui fait partie de JDK (à l’adresse: JAVA__HOME]/bin).

A partir de l’invite de commande:

wsimport -s . -p com.baeldung.jaxws.server.topdown employeeservicetopdown.wsdl

Options de ligne de commande utilisées: -p spécifie le package cible. -s spécifie où placer les fichiers source générés.

Les fichiers générés:

  • EmployeeServiceTopDown.java - est l’interface de noeud final de service

(SEI) qui contient les définitions de méthodes ** ObjectFactory.java - contient les méthodes d’usine pour créer des instances de

classes de schéma dérivées par programmation ** EmployeeServiceTopDown Service.java__ - est la classe du fournisseur de service

pouvant être utilisé par un client JAX-WS

5.2. Interface de noeud final de service Web

L’outil wsimport a généré l’interface de noeud final du service Web EmployeeServiceTopDown . Il déclare les méthodes de service Web:

@WebService(
  name = "EmployeeServiceTopDown",
  targetNamespace = "http://topdown.server.jaxws.baeldung.com/")
@SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
@XmlSeeAlso({
    ObjectFactory.class
})
public interface EmployeeServiceTopDown {
    @WebMethod(
      action = "http://topdown.server.jaxws.baeldung.com/"
      + "EmployeeServiceTopDown/countEmployees")
    @WebResult(
      name = "countEmployeesResponse",
      targetNamespace = "http://topdown.server.jaxws.baeldung.com/",
      partName = "parameters")
    public int countEmployees();
}

5.3. Implémentation du service Web

L’outil wsimport a créé la structure du service Web. Nous devons créer l’implémentation du service Web:

@WebService(
  name = "EmployeeServiceTopDown",
  endpointInterface = "com.baeldung.jaxws.server.topdown.EmployeeServiceTopDown",
  targetNamespace = "http://topdown.server.jaxws.baeldung.com/")
public class EmployeeServiceTopDownImpl
  implements EmployeeServiceTopDown {

    @Inject
    private EmployeeRepository employeeRepositoryImpl;

    @WebMethod
    public int countEmployees() {
        return employeeRepositoryImpl.count();
    }
}

6. Approche ascendante (dernier contrat)

Dans une approche ascendante, nous devons créer à la fois l’interface de point final et les classes d’implémentation. Le WSDL est généré à partir des classes lorsque le service Web est publié.

Créons un service Web qui effectuera des opérations CRUD simples sur des données Employee .

6.1. La classe de modèle

La classe de modèle Employee :

public class Employee {
    private int id;
    private String firstName;

   //standard getters and setters
}

6.2. Interface de noeud final de service Web

L’interface de point de terminaison de service Web qui déclare les méthodes de service Web:

@WebService
public interface EmployeeService {
    @WebMethod
    Employee getEmployee(int id);

    @WebMethod
    Employee updateEmployee(int id, String name);

    @WebMethod
    boolean deleteEmployee(int id);

    @WebMethod
    Employee addEmployee(int id, String name);

   //...
}

Cette interface définit un contrat abstrait pour le service Web. Les annotations utilisées:

**

**

  • @ WebResult est utilisé pour personnaliser le nom de l’élément XML qui

représente la valeur de retour

6.3. Implémentation du service Web

La classe d’implémentation de l’interface de noeud final de service Web:

@WebService(endpointInterface = "com.baeldung.jaxws.EmployeeService")
public class EmployeeServiceImpl implements EmployeeService {

    @Inject
    private EmployeeRepository employeeRepositoryImpl;

    @WebMethod
    public Employee getEmployee(int id) {
        return employeeRepositoryImpl.getEmployee(id);
    }

    @WebMethod
    public Employee updateEmployee(int id, String name) {
        return employeeRepositoryImpl.updateEmployee(id, name);
    }

    @WebMethod
    public boolean deleteEmployee(int id) {
        return employeeRepositoryImpl.deleteEmployee(id);
    }

    @WebMethod
    public Employee addEmployee(int id, String name) {
        return employeeRepositoryImpl.addEmployee(id, name);
    }

   //...
}

7. Publication des points de terminaison de service Web

Pour publier les services Web (de haut en bas et de bas en haut), nous devons transmettre une adresse et une instance de l’implémentation du service Web à la méthode publish () de la classe javax.xml.ws.Endpoint :

public class EmployeeServicePublisher {
    public static void main(String[]args) {
        Endpoint.publish(
          "http://localhost:8080/employeeservicetopdown",
           new EmployeeServiceTopDownImpl());

        Endpoint.publish("http://localhost:8080/employeeservice",
          new EmployeeServiceImpl());
    }
}

Nous pouvons maintenant exécuter EmployeeServicePublisher pour démarrer le service Web. Pour utiliser les fonctionnalités CDI, les services Web peuvent être déployés en tant que fichier WAR sur des serveurs d’applications tels que WildFly ou GlassFish.

8. Client de service Web distant

Créons maintenant un client JAX-WS pour se connecter au service Web EmployeeService à distance.

8.1. Génération d’artefacts client

Pour générer des artefacts de client JAX-WS, nous pouvons à nouveau utiliser l’outil wsimport :

wsimport -keep -p com.baeldung.jaxws.client http://localhost:8080/employeeservice?wsdl

La classe EmployeeService Service générée encapsule la logique permettant d’obtenir le port du serveur à l’aide de URL et QName__.

8.2. Connexion au service Web

Le client de service Web utilise EmployeeService Service__ généré pour se connecter au serveur et effectuer des appels de service Web à distance:

public class EmployeeServiceClient {
    public static void main(String[]args) throws Exception {
        URL url = new URL("http://localhost:8080/employeeservice?wsdl");

        EmployeeService__Service employeeService__Service
          = new EmployeeService__Service(url);
        EmployeeService employeeServiceProxy
          = employeeService__Service.getEmployeeServiceImplPort();

        List<Employee> allEmployees
          = employeeServiceProxy.getAllEmployees();
    }
}

9. Conclusion

Cet article est une introduction rapide aux services Web SOAP utilisant JAX-WS .

Nous avons utilisé les approches ascendante et descendante pour créer des services Web SOAP à l’aide de l’API JAX-WS. Nous avons également écrit un client JAX-WS pouvant se connecter à distance au serveur et effectuer des appels de service Web.

Le code source complet est disponible à l’adresse over sur GitHub .