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 UC
Benutzeroberflä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); }
UC
beschreibt 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.
UC
wird über die @WebService
Annotation als SEI deklariert . Wenn eine Java-Schnittstelle oder -Klasse mit Anmerkungen versehen wird @WebService
, beschreiben alle public
Methoden, deren Parameter, Rückgabewerte und deklarierte Ausnahmen den in Abschnitt 5 der JAX-RPC 1.1-Spezifikation definierten Regeln entsprechen, Webdienstvorgänge. Denn nur public
Methoden in Interfaces deklariert werden, das public
ist 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 @WebMethod
dies 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 UCImpl
Klasse 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; } }
UCImpl
beschreibt 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 endpointInterface
Element verbindet dieses SIB mit seiner SEI und ist erforderlich, um undefinierte Porttypfehler beim Ausführen der später vorgestellten Clientanwendung zu vermeiden.
Die implements UC
Klausel ist nicht unbedingt erforderlich. Wenn diese Klausel nicht vorhanden ist, wird die UC
Schnittstelle ignoriert (und ist redundant). Es ist jedoch eine gute Idee, diese beizubehalten, implements UC
damit der Compiler überprüfen kann, ob die SEI-Methoden im SIB implementiert wurden.
Die Methodenheader des SIB werden nicht mit Anmerkungen versehen, @WebMethod
da diese Anmerkung normalerweise im Kontext der SEI verwendet wird. Wenn Sie public
dem 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 true
zu @WebMethod
's exclude
Element 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 UCPublisher
Anwendung, 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 EndPoint
Klassenmethode der Endpoint publish(String address, Object implementor)
Klasse einmal aufgerufen werden. Der address
Parameter 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 /UC
als Veröffentlichungspfad gewählt. Der implementor
Parameter identifiziert eine Instanz von UC
SIB.
Die publish()
Methode erstellt und veröffentlicht einen Endpunkt für das angegebene implementor
Objekt an der angegebenen Stelle address
und verwendet die implementor
Anmerkungen 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:
- Erstellen Sie im aktuellen Verzeichnis ein
ca
Verzeichnis.ca
Erstellen Sie innerhalb einjavajeff
Verzeichnis.javajeff
Erstellen Sie schließlich innerhalb einuc
Verzeichnis. - Kopieren Sie Listing 1 in eine
UC.java
Quelldatei und speichern Sie diese Datei inca/javajeff/uc
. - Kopieren Sie Listing 2 in eine
UCImpl.java
Quelldatei und speichern Sie diese Datei inca/javajeff/uc
. - Kopieren Sie Listing 3 in eine
UCPublisher.java
Quelldatei und speichern Sie diese Datei im aktuellen Verzeichnis, das dasca
Verzeichnis 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.ws
in 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.ws
in 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.ca
anstelle 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 definitions
Stammelement, wodurch ein WSDL-Dokument nur aus einer Reihe von Definitionen besteht. Dieses Element enthält verschiedene xmlns
Attribute zum Identifizieren verschiedener Standard-Namespaces sowie targetNameSpace
und name
Attribute:
- Das
targetNamespace
Attribut erstellt einen Namespace für alle benutzerdefinierten Elemente im WSDL-Dokument (z. B. dasc2f
über dasmessage
Element 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-import
Element identifiziert werden . In ähnlicher Weise erstellt dastargetNamespace
Attribut, das auf demschema
Element einer XML-Schema-basierten Datei angezeigt wird, einen Namespace für die benutzerdefinierten einfachen Typhemente, Attributelemente und komplexen Tybelemente. - Das
name
Attribut identifiziert den Webdienst und wird nur zur Dokumentation des Dienstes verwendet.
Verschachtelte innerhalb definitions
sind types
, message
, portType
, binding
, und service
Elemente: