Webdienste in Java SE, Teil 2: Erstellen von SOAP-Webdiensten

JAX-WS unterstützt SOAP-basierte Webdienste. Teil 2 dieser vierteiligen Serie über Java SE-Webdienste definiert einen SOAP-basierten Einheitenkonvertierungs-Webdienst, erstellt und überprüft diesen Webdienst lokal über den standardmäßigen Lightweight-HTTP-Server (siehe Teil 1) und interpretiert das WSDL-Dokument des Dienstes und greift von einem einfachen Client auf den Dienst zu.

Definieren eines Webdienstes zur Einheitenumrechnung

Der Webdienst zur Einheitenumrechnung, den ich UC genannt habe, besteht aus vier Funktionen zum Umrechnen zwischen Zentimetern und Zoll sowie zwischen Grad Fahrenheit und Grad Celsius. Obwohl dieses Beispiel als einzelne Java-Klasse erstellt werden könnte, habe ich mich für Best Practices entschieden, indem ich es als Java-Schnittstelle und Java-Klasse entworfen habe. Listing 1 zeigt die UCBenutzeroberfläche des Webdienstes .

Listing 1. Die Service-Endpunktschnittstelle des UC-Webdienstes

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

UCbeschreibt eine Service Endpoint Interface (SEI) , eine Java-Schnittstelle, die die Operationen einer Webdienstschnittstelle in Bezug auf abstrakte Java-Methoden verfügbar macht. Clients kommunizieren über ihre SEIs mit SOAP-basierten Webdiensten.

UCwird über die @WebServiceAnnotation als SEI deklariert . Wenn eine Java-Schnittstelle oder -Klasse mit Anmerkungen versehen wird @WebService, beschreiben alle publicMethoden, deren Parameter, Rückgabewerte und deklarierte Ausnahmen den in Abschnitt 5 der JAX-RPC 1.1-Spezifikation definierten Regeln entsprechen, Webdienstvorgänge. Denn nur publicMethoden in Interfaces deklariert werden, das publicist reservierte Wort nicht notwendig , wenn erklärt c2f(), cm2in(), f2c(), und in2cm(). Diese Methoden sind implizit public.

Jede Methode ist auch mit Anmerkungen versehen @WebMethod. Obwohl @WebMethoddies in diesem Beispiel nicht unbedingt erforderlich ist, verstärkt seine Anwesenheit die Tatsache, dass die mit Anmerkungen versehene Methode einen Webdienstvorgang verfügbar macht.

Listing 2 zeigt die UCImplKlasse des Webdienstes .

Listing 2. Die Service Implementation Bean des UC-Webdienstes

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

UCImplbeschreibt eine Service Implementation Bean (SIB) , die eine Implementierung der SEI bereitstellt. Diese Klasse wird über die @WebService(endpointInterface = "ca.javajeff.uc.UC")Annotation als SIB deklariert . Das endpointInterfaceElement verbindet dieses SIB mit seiner SEI und ist erforderlich, um undefinierte Porttypfehler beim Ausführen der später vorgestellten Clientanwendung zu vermeiden.

Die implements UCKlausel ist nicht unbedingt erforderlich. Wenn diese Klausel nicht vorhanden ist, wird die UCSchnittstelle ignoriert (und ist redundant). Es ist jedoch eine gute Idee, diese beizubehalten, implements UCdamit der Compiler überprüfen kann, ob die SEI-Methoden im SIB implementiert wurden.

Die Methodenheader des SIB werden nicht mit Anmerkungen versehen, @WebMethodda diese Anmerkung normalerweise im Kontext der SEI verwendet wird. Wenn Sie publicdem SIB jedoch eine Methode hinzufügen (die den Regeln in Abschnitt 5 der JAX-RPC 1.1-Spezifikation entspricht) und diese Methode keine Webdienstoperation verfügbar macht, würden Sie den Methodenheader mit Anmerkungen versehen @WebMethod(exclude = true). Durch Zuweisen truezu @WebMethod's excludeElement verhindern Sie, dass diese Methode einer Operation zugeordnet wird.

Dieser Webdienst kann veröffentlicht werden, sodass von Clients aus auf ihn zugegriffen werden kann. Listing 3 zeigt eine UCPublisherAnwendung, die diese Aufgabe im Kontext des standardmäßigen Lightweight-HTTP-Servers ausführt.

Listing 3. UC veröffentlichen

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

Zum Veröffentlichen des Webdienstes muss die EndPointKlassenmethode der Endpoint publish(String address, Object implementor)Klasse einmal aufgerufen werden. Der addressParameter gibt den dem Webdienst zugewiesenen URI an. Ich habe mich entschieden, diesen Webdienst auf dem lokalen Host zu veröffentlichen, indem ich localhost(entspricht der IP-Adresse 127.0.0.1) und die Portnummer 9901(die höchstwahrscheinlich verfügbar ist) angegeben habe. Außerdem habe ich willkürlich /UCals Veröffentlichungspfad gewählt. Der implementorParameter identifiziert eine Instanz von UCSIB.

Die publish()Methode erstellt und veröffentlicht einen Endpunkt für das angegebene implementorObjekt an der angegebenen Stelle addressund verwendet die implementorAnmerkungen von, um WSDL- und XML-Schemadokumente (Web Services Definition Language) zu erstellen. Dadurch wird die erforderliche Serverinfrastruktur von der JAX-WS-Implementierung basierend auf einer Standardkonfiguration erstellt und konfiguriert. Darüber hinaus führt diese Methode dazu, dass die Anwendung unbegrenzt ausgeführt wird. (Drücken Sie auf Windows-Computern gleichzeitig die Tasten Strg und C, um die Anwendung zu beenden.)

Erstellen und Überprüfen des Webdienstes

Es ist nicht schwierig, den zuvor definierten UC-Webdienst zu erstellen. Zunächst müssen Sie eine geeignete Verzeichnisstruktur erstellen, die die entsprechenden Dateien enthält. Führen Sie diese Aufgabe aus, indem Sie die folgenden Schritte ausführen:

  1. Erstellen Sie im aktuellen Verzeichnis ein caVerzeichnis. caErstellen Sie innerhalb ein javajeffVerzeichnis. javajeffErstellen Sie schließlich innerhalb ein ucVerzeichnis.
  2. Kopieren Sie Listing 1 in eine UC.javaQuelldatei und speichern Sie diese Datei in ca/javajeff/uc.
  3. Kopieren Sie Listing 2 in eine UCImpl.javaQuelldatei und speichern Sie diese Datei in ca/javajeff/uc.
  4. Kopieren Sie Listing 3 in eine UCPublisher.javaQuelldatei und speichern Sie diese Datei im aktuellen Verzeichnis, das das caVerzeichnis enthält .

Die nächste Aufgabe besteht darin, diese Quelldateien zu kompilieren. Angenommen, Sie haben keine Verzeichnisse geändert, führen Sie den folgenden Befehl aus, um diese Quelldateien in Java SE 9 zu kompilieren ( --add-modules java.xml.wsin Java SE 6, 7 oder 8 weglassen ):

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

Wenn diese Quelldateien erfolgreich kompiliert wurden, führen Sie den folgenden Befehl aus, um diese Anwendung in Java 9 auszuführen ( --add-modules java.xml.wsin Java SE 6, 7 oder 8 weglassen ):

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

Verwenden Sie während der Ausführung der Anwendung einen Webbrowser, um zu überprüfen, ob dieser Webdienst ordnungsgemäß ausgeführt wird, und um auf das WSDL-Dokument zuzugreifen. Starten Sie Ihren bevorzugten Webbrowser und geben Sie die folgende Zeile in die Adressleiste ein:

//localhost:9901/UC

Abbildung 1 zeigt die resultierende Webseite im Google Chrome-Webbrowser.

Abbildung 1. Die Webseite von UC enthält detaillierte Informationen zum veröffentlichten Webdienst

Abbildung 1 zeigt die qualifizierten Dienst- und Portnamen des Webdienstendpunkts. (Beachten Sie, dass der Paketname invertiert wurde - uc.javajeff.caanstelle von ca.javajeff.uc). Ein Client verwendet diese Namen, um auf den Dienst zuzugreifen.

In Abbildung 1 sind auch der Adress-URI des Webdienstes, der Speicherort des WSDL-Dokuments des Webdienstes (der durch die Abfragezeichenfolge angehängte Webdienst-URI ?wsdl) und der paketqualifizierte Name der Webdienst-Implementierungsklasse dargestellt.

Interpretieren des WSDL-Dokuments des Webdienstes

Der Speicherort des WSDL-Dokuments des UC-Webdienstes wird als Link angezeigt. Klicken Sie auf diesen Link, um das WSDL-Dokument anzuzeigen, dessen Inhalt in Listing 4 dargestellt ist.

Listing 4. Das WSDL-Dokument von UC

Ein WSDL-Dokument ist ein XML-Dokument mit einem definitionsStammelement, wodurch ein WSDL-Dokument nur aus einer Reihe von Definitionen besteht. Dieses Element enthält verschiedene xmlnsAttribute zum Identifizieren verschiedener Standard-Namespaces sowie targetNameSpaceund nameAttribute:

  • Das targetNamespaceAttribut erstellt einen Namespace für alle benutzerdefinierten Elemente im WSDL-Dokument (z. B. das c2füber das messageElement mit diesem Namen definierte Element). Dieser Namespace wird verwendet, um zwischen benutzerdefinierten Elementen des aktuellen WSDL-Dokuments und benutzerdefinierten Elementen importierter WSDL-Dokumente zu unterscheiden, die über das WSDL- importElement identifiziert werden . In ähnlicher Weise erstellt das targetNamespaceAttribut, das auf dem schemaElement einer XML-Schema-basierten Datei angezeigt wird, einen Namespace für die benutzerdefinierten einfachen Typhemente, Attributelemente und komplexen Tybelemente.
  • Das nameAttribut identifiziert den Webdienst und wird nur zur Dokumentation des Dienstes verwendet.

Verschachtelte innerhalb definitionssind types, message, portType, binding, und serviceElemente: