Einführung in JAX-WS

1. Überblick

Java-API für XML-Webdienste (JAX-WS) ist eine standardisierte API zum Erstellen und Verwenden von SOAP-Webdiensten (Simple Object Access Protocol).

In diesem Artikel erstellen wir einen SOAP-Webdienst und stellen eine Verbindung mit JAX-WS her.

2. SEIFE

SOAP ist eine XML-Spezifikation zum Senden von Nachrichten über ein Netzwerk.

SOAP ist XML-schwer und kann daher am besten mit Tools/Frameworks verwendet werden. JAX-WS ist ein Framework, das die Verwendung von SOAP vereinfacht. Es ist Teil des Standard-Java.

3. Top-Down vs. Bottom-Up

Es gibt zwei Möglichkeiten, SOAP-Webdienste zu erstellen. Wir können einen Top-Down-Ansatz oder einen Bottom-Up-Ansatz wählen.

Bei einem Top-Down-Ansatz (Vertrag zuerst) wird ein WSDL-Dokument erstellt und die erforderlichen Java-Klassen werden aus der WSDL generiert. In einem Bottom-up-Ansatz (letzter Kontrakt)

Da Ihre WSDL jedoch aus den Java-Klassen generiert wird, kann jede Änderung des Codes zu einer Änderung der WSDL führen. Dies ist beim Top-Down-Ansatz nicht der Fall.

4. Web Services Definition Language (WSDL)

WSDL ist eine Vertragsdefinition der verfügbaren Dienste. Es ist eine Spezifikation von Eingabe-/Ausgabemeldungen und wie der Webdienst aufgerufen wird. Es ist sprachneutral und in XML definiert.

Schauen wir uns die wichtigsten Elemente eines WSDL-Dokuments an.

4.1. Definitionen

Das definitions -Element ist das Wurzelelement aller WSDL-Dokumente. Sie definiert den Namen, den Namespace usw. des Dienstes und kann, wie Sie sehen, recht umfangreich sein:

<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. Typen

Das types -Element definiert die vom Web-Service verwendeten Datentypen. WSDL verwendet XSD (XML Schema Definition) als das Typsystem, das bei der Interoperabilität hilft:

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

4.3. Mitteilungen

Das message -Element liefert eine abstrakte Definition der übertragenen Daten. Jedes message -Element beschreibt die Eingabe oder Ausgabe einer Servicemethode und die möglichen Ausnahmen:

<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. Vorgänge und Anschlusstypen

Das portType -Element beschreibt jede auszuführende operation und alle betroffenen message -Elemente. Die Operation getEmployee gibt beispielsweise die Anforderung input , output und eine mögliche fault -Ausnahme an, die vom Webdienst operation ausgelöst wird:

<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. Bindungen

Das binding -Element enthält Protokoll- und Datenformatdetails für jeden 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. Dienste und Häfen

Das service -Element definiert die vom Web-Service unterstützten Ports.

Das port -Element in service definiert den name , binding und die address des Dienstes:

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

5. Top-Down-Ansatz (Vertrag zuerst)

Beginnen wir mit einem Top-Down-Ansatz, indem Sie eine WSDL-Datei employeeservicetopdown.wsdl. erstellen. Der Einfachheit halber gibt es nur eine Methode:

<?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. Web Service-Quelldateien aus WSDL generieren

Um Web-Service-Quelldateien aus einem WSDL-Dokument zu generieren, können Sie das Tool wsimport verwenden, das Teil des JDK ist (unter $ JAVA__HOME /bin).

Von der Eingabeaufforderung:

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

Verwendete Befehlszeilenoptionen: -p gibt das Zielpaket an. -s gibt an, wo die generierten Quelldateien abgelegt werden sollen.

Die generierten Dateien:

  • EmployeeServiceTopDown.java - ist die Service-Endpunktschnittstelle

(SEI), das Methodendefinitionen enthält ** ObjectFactory.java - enthält Factory-Methoden zum Erstellen von Instanzen

Schema abgeleitete Klassen programmgesteuert ** EmployeeServiceTopDown Service.java__ - ist die Service Provider-Klasse

das kann von einem JAX-WS-Client verwendet werden

5.2. Web Service Endpoint Interface

Das wsimport -Tool hat die Web-Service-Endpunktschnittstelle EmployeeServiceTopDown generiert. Darin werden die Webdienstmethoden angegeben:

@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. Web Service Implementierung

Das wsimport -Tool hat die Struktur des Web-Service erstellt. Wir müssen die Implementierung des Webservices erstellen:

@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. Bottom-Up (Contract-Last) -Ansatz

In einem Bottom-up-Ansatz müssen wir sowohl die Endpunktschnittstelle als auch die Implementierungsklassen erstellen. Die WSDL wird aus den Klassen generiert, wenn der Webdienst veröffentlicht wird.

Erstellen Sie einen Webdienst, der einfache CRUD-Vorgänge für Employee -Daten ausführt.

6.1. Die Modellklasse

Die Employee -Modellklasse:

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

   //standard getters and setters
}

6.2. Web Service Endpoint Interface

Die Web-Service-Endpunkt-Schnittstelle, die die Web-Service-Methoden deklariert:

@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);

   //...
}

Diese Schnittstelle definiert einen abstrakten Vertrag für den Webservice. Die verwendeten Anmerkungen:

**

**

  • @ WebResult wird verwendet, um den Namen des XML-Elements anzupassen

repräsentiert den Rückgabewert

6.3. Web Service Implementierung

Die Implementierungsklasse der Web-Service-Endpunktschnittstelle:

@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. Veröffentlichen der Web-Service-Endpunkte

Um die Webservices (Top-Down und Bottom-Up) zu veröffentlichen, müssen wir eine Adresse und eine Instanz der Webservice-Implementierung an die publish () -Methode der Klasse javax.xml.ws.Endpoint übergeben:

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());
    }
}

Wir können jetzt EmployeeServicePublisher ausführen, um den Webdienst zu starten. Um CDI-Funktionen nutzen zu können, können die Webservices als WAR-Datei auf Anwendungsservern wie WildFly oder GlassFish bereitgestellt werden.

8. Remote-Webdienst-Client

Erstellen Sie jetzt einen JAX-WS-Client, um eine Remote-Verbindung zum EmployeeService -Webdienst herzustellen.

8.1. Client-Artefakte generieren

Um JAX-WS-Client-Artefakte zu generieren, können Sie erneut das wsimport -Tool verwenden:

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

Die generierte Klasse EmployeeService Service kapselt die Logik, um den Serverport mithilfe von URL und QName__ abzurufen.

8.2. Verbindung zum Web Service

Der Webdienstclient verwendet den generierten EmployeeService Service__, um eine Verbindung zum Server herzustellen und Webdienstaufrufe aus der Ferne durchzuführen:

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. Fazit

Dieser Artikel ist eine schnelle Einführung in SOAP-Webdienste mit JAX-WS .

Wir haben sowohl Bottom-Up- als auch Top-Down-Ansätze verwendet, um SOAP-Webdienste mithilfe der JAX-WS-API zu erstellen. Wir haben auch einen JAX-WS-Client geschrieben, der sich remote mit dem Server verbinden und Webdienstanrufe durchführen kann.

Der vollständige Quellcode ist verfügbar unter over auf GitHub .