Berater und Strategen preisen gerne die Segnungen von serviceorientierten Architekturen (SOA). Admins und Entwickler hören dann weg, wenn nicht greifbar ist, wie die Technik funktioniert. Zeit für sie, selbst einen Webservice zu programmieren, bei dem heterogene Anwendungen miteinander kooperieren.
IT-Strategen verlieren sich gerne im Allgemeinen. Serviceorientierte Architekturen (SOA) halten viele ebenso für die Universallösung wie der dort am häufigsten eingesetzte Kommunikationsstandard Webservices [1]. Aus akademischer Sicht spricht einiges dafür, aber wieso ist dieses Thema immer so unkonkret und missverständlich, fragen viele Anwender.
Das fängt schon mit dem Namen an: Ein Webservice hat per se nicht viel mit dem World Wide Web zu tun, außer vielleicht dem Detail, dass sowohl Webservices als auch WWW dasselbe Transportprotokoll HTTP benutzen. Webservices müssen keine Web-Applikationen und auch nicht über das WWW öffentlich erreichbar sein. Vermutlich trifft dies nur auf wenige Anwendungen zu, die Webservices verwenden.
Auf der anderen Seite erlauben sie, komplexe Anwendungen auf mehrere Systeme zu verteilen. Wie das genau geht, erläutert ein fiktives Anwendungsbeispiel: Ein Client stellt eine Kundenanfrage in Textform und ein Server beantwortet sie in einer Weise, wie sie typischerweise ein Call Center liefert. Beide unterhalten sich per Webservice. Das Beispiel ist in Java implementiert, eine Sprache, die SOA-Entwickler gern einsetzen.
Miteinander reden
Oft besteht die Architektur eines Unternehmens aus mehreren heterogenen Systemen. Die wollen untereinander Funktionen aufrufen. Es gibt viele Techniken, um Remote Procedure Calls (RPCs) umzusetzen, und dafür vermutlich noch viel mehr Namen. Ein Webservice ist ein Ansatz, der sich auf zwei Aspekte konzentriert. Erstens greift er auf bestehende Standards und Techniken zurück, um zu kommunizieren. Zweitens legt er einen Schwerpunkt darauf, bei Bedarf möglichst einfach von einem Dienstanbieter auf einen anderen zu wechseln, ohne die Anwendung selbst nennenswert zu verändern.
Um diese Ziele zu erreichen ist ein hohes Maß an Abstimmung notwendig. Eine Reihe von Standards definiert, was ein en Webservice ausmacht [2]. Die wichtigsten sind hierbei XML als grundlegende Beschreibungssprache, SOAP als Nachrichtenformat in XML, WSDL als Schnittstellenbeschreibung in XML und HTTP als ein mögliches Transportprotokoll. Im Unterschied zu früheren Ansätzen wie DCOM oder Corba wurden Webservices entworfen, um Systeme über das Internet und über Firewall-Grenzen hinweg zu verbinden. So integrieren Systemarchitekten ihre Anwendungen leichter [3].
XML beschreibt Nachrichten
XML beschreibt sowohl die Schnittstellen als auch die darüber ausgetauschten Nachrichten – unabhängig davon, für welche Plattform sie der Entwickler entworfen hat (siehe Abbildung 1). In der Praxis laufen viele Systeme unter Java, aber es lassen sich durchaus auch Mainframes oder kleinere Serversystem mit eigenen Programmiersprachen anbinden. XML fungiert dabei als eine Art universelle Sprache. Die Partner können so miteinander interagieren, ohne dass ihre jeweiligen Entwickler sie auf technologischer Ebene angepasst haben. Wer solche Systeme einsetzt, hat den Vorteil, dass er keine Adapter für jedes System benötigt, mit dem er kommunizieren will.

Abbildung 1: Webservices nutzen XML, um leichter zwischen unterschiedlichen Technologien zu vermitteln. So spielen Endianness oder Textcodierung keine Rolle mehr.
SOAP ist ein leichtgewichtiges Protokoll, mit dessen Hilfe Webservices Informationen austauschen [4]. Es verwendet einerseits XML, um die Nachrichten zu beschreiben und andererseits Protokolle wie HTTP oder SMTP, um sie auszutauschen.
Die Ziele von SOAP sind Einfachheit und Erweiterbarkeit. Dies bedeutet, dass SOAP keine Querschnittsbelange wie Sicherheit oder Routing definiert. Andere Standards setzten auf SOAP auf und erweitern es so. Eine SOAP-Nachricht verhält sich wie eine Art Briefumschlag, der Steuerdaten und Nutzdaten enthält (siehe Abbildung 2). Der Inhalt der Datenfelder ist applikationsspezifisch.

Abbildung 2: Eine SOAP-Nachricht enthält mehrere Datenbereiche. Sie besteht aus Steuerdaten und Nutzlast, ähnlich wie ein Briefumschlag.
SOAP tauscht Anfragen aus
Steuerdaten sind beispielsweise Kontextinformationen, um eine Nachricht zu verarbeiten. Die Trennung hat den Vorteil, dass ein Programm nicht immer die gesamte Nachricht betrachten muss. Auch bei einem realen Briefumschlag reicht es dem Briefträger, auf das Adressfeld zu schauen, um ihn korrekt zuzustellen.
Webservices reicht es nicht, einen Mechanismus zum Austausch von Nachrichten zu haben. Eine einheitliche Form, um Schnittstellen zu beschreiben ist ebenfalls Teil des Konzeptes. Diese legen Entwickler in einer XML-Datei ab, die dem WSDL-Standard (Web Service Description Language) folgt [5]. WSDL beschreibt die aufrufbaren Operationen und die Datentypen einer Schnittstelle (siehe Abbildung 3).

Abbildung 3: Eine WSDL-Datei beschreibt viele Aspekte einer Schnittstelle. Damit greifen Clients ohne sonstiges Wissen auf den Webservice zu.
Weiter legt sie mögliche Kommunikationsprotokolle und die Adresse des Service fest. Oft verwenden Anwendungen HTTP als Protokoll, die Adresse ist dann ein URL. Diese Informationen benötigen Entwickler, um Client und Server zu entwerfen. WSDL definiert die Aspekte Typen, Nachrichten, Porttypen, Verbindungen, Ports und Dienste, die Tabelle 1 näher erläutert.
|
Tabelle 1: Aufbau von |
|---|
Dienste inserieren in WSDL
Mit einem Encoding-Stil bestimmt WSDL, wie der Webservice Datentypen in den SOAP-Nachrichten abbilden soll. Der Entwickler hat dabei mehrere Alternativen: Der Stil »document-literal« bietet aktuell die beste Kompatibilität und hat sich gegen früher verwendete Stile wie »rpc-encoded« durchgesetzt.
In der Theorie reicht es also für einen Webservice, Client und Server zu implementieren und die Schnittstelle mit einer WSDL-Datei zu beschreiben, sodass die beiden SOAP-Nachrichten per HTTP austauschen. Die WSDL-Beschreibung lässt sich sogar halbautomatisch mit Werkzeugen aus dem Quellcode erzeugen. Einige Hürden sind jedoch in der Praxis noch zu überwinden.
Insgesamt gibt es über 70 Standards in unterschiedlichen Versionen, die sich mit Aspekten wie Sicherheit, Nachrichtenübermittlung oder Verlässlichkeit von Webservices befassen. Unterschiedlichen Gremien und Firmenkonsortien haben sie ins Leben gerufen. Zusätzlich überlappen sie oder sind redundant.
Standards standardisieren
Hinzu kommt, dass ein Standard wie beispielsweise SOAP viele Freiheitsgrade besitzt, um Aspekte seiner Definition umzusetzen. Konsequenz: Wer SOAP verwendet, darf sich nicht sicher sein, dass er damit automatisch und erfolgreich mit heterogenen Systemen kommuniziert. Vielmehr muss die Interpretation des Standards auf beiden Seiten übereinstimmen. Um dieser Situation Herr zu werden, entschlossen sich 2002 namhafte Firmen zur Gründung der Webservices Interoperability Organization WS-I [6]. Sie standardisiert die Standards.
Sie definiert Profile, die einen oder mehrere Standards in bestimmten Versionen mit zusätzlichen Einschränkungen oder Ergänzungen festlegt. Verwendet ein Entwickler ein Profil, schafft er sich eine gute Grundlage für interoperable Services ohne Inkompatibilitäten.
Bei der Kommunikation über Unternehmensgrenzen hinweg spielt Sicherheit eine große Rolle. Webservices beherrschen sowohl Transport- als auch Nachrichtensicherheit. Die erste beschreibt die Punkt-zu-Punkt-Sicherheit zwischen zwei Systemen. Das bedeutet, dass die Sicherheit der Nachricht nur zwischen Sender und Empfänger gewährleistet ist. Prominentestes Beispiel dafür ist HTTPS. Service-Aufrufe über richtig eingesetztes HTTPS bieten somit ein Mindestmaß an Sicherheit. Es reicht aus, um zwei sichere Domänen über eine unsichere Leitung zu verbinden.
Begleitschutz für Daten
Die Standards XML-Signature und XML-Encryption schaffen die zweite Form der Sicherheit: Die Spezifikationen bestimmen, wie Nachrichten unversehrt und verschlüsselt bleiben. Damit erreichen Entwickler eine Ende-zu-Ende-Sicherheit, die auch über mehrere Systeme hinweg gewahrt bleibt.
Die Systemvoraussetzungen für einen minimalen Webservice mit XML, SOAP und HTTP sind gering. Für Entwickler bedeutet dies jedoch, XML-Nachrichten verarbeiten zu müssen. Daher bieten viele Programmiersprachen Bindings und Generatoren zu den Webservices an, die es dem Entwickler erlauben, in gewohnter Weise zu programmieren.
Die in Java implementierte Anwendung »KundenAnfrage« in Listing 1 realisiert eine Schnittstelle »stelleAnfrage()« als Webservice. Ihr Server gibt auskunftsuchenden Clients eine etwas zynische Antwort zurück. Im Umfeld von Java tummelt sich ein ganzes Ökosystem von Open-Source-Frameworks wie Apache Axis2, Apache CXF, Spring WS oder Sun Metro. Sie ermöglichen es dem Programmierer, seine Idee umzusetzen, anstatt sich auf die Technologie zu konzentrieren. Alle eignen sich für den produktiven Einsatz.
|
Listing 1: |
|---|
01 package de.lm.wssample.server;
02
03 import javax.jws.WebService;
04
05 @WebService
06 public class KundenAnfrage
07 {
08 public String stelleAnfrage(String anfrageText)
09 {
10 return "Ihre Anfrage ist uns wichtig. " +
11 "Sie fragten: "" + anfrageText +
12 "". Wir bearbeiten ihre Frage irgendwann.";
13 }
14 }
|
Webservice selbst programmieren
Axis2 genießt viel Unterstützung durch eine Entwickler-Community und zeichnet sich durch ausführliche Dokumentation für Einsteiger aus [7]. Das Apache-Projekt entwickelt seit vier Jahren das Framework, aktuell ist Version 1.4.1. Axis2 unterstützt zudem weitere WS-Standards und bietet viele Annehmlichkeiten für professionelle Entwickler.
Für das Beispiel reicht jedoch bereits das reine Java Development Kit als Umgebung aus. Das JDK bringt ab der Version 6 alles Nötige mit, um einen Webservice und den Client zu entwickeln. Frühere Versionen reichen für dieses Beispiel nicht aus. Insbesondere ist das Java API for XML Web Services (JAX-WS) notwendig [8]. Als Beigabe enthält es einen kleinen Server, der für dieses Beispiel ausreicht. Interessierte Programmierer installieren mit dem Befehl
aptitude install sun-java-jdk6
die Pakete auf einem Debian- oder Ubuntu-System und setzen die Umgebungsvariable »JAVA_HOME« auf den Ordner der aktuellen Installation. Das Beispiel erwartet die zwei Unterverzeichnisse »bin« und »src«.
Server beantwortet Fragen
Es gibt zwei Wege, um eine Schnittstelle als Webservice anzubieten: Einige Entwickler beginnen bei der Schnittstellendefinition mit dem WSDL-Dokument und generieren daraus eine Java-Klasse. Umgekehrt ist es ebenfalls möglich, eine WSDL-Datei aus einer Java-Klasse zu erzeugen. Das ist zum Starten einfacher, da sich so die Zusammenhänge zwischen der Java- und der XML-Welt an einem Beispiel erschließen lassen.
Die Datentypen der Schnittstelle sollten keine spezifischen Typen der Programmiersprache oder des Frameworks der Serverseite enthalten, da sie nicht leicht in XML und damit nicht im Client abbildbar sind. Zur Erinnerung: Webservices sollen die Kommunikation zwischen unterschiedlichen Technologien ermöglichen. Beispielsweise unterstützen einige Sprachen Vererbung oder Aufzählungstypen nicht oder haben eine andere Semantik. Gut lassen sich atomare Typen, Arrays und Klassen verwenden, die ihrerseits aus diesen Bausteinen bestehen. Eine Schachtelung der Typen ist möglich.
Wer mit der WSDL-Definition beginnen möchte, dem bietet XML-Schema ein mächtiges Werkzeug, das Datentypen beschreibt. Weitsichtige nutzen jedoch nach Möglichkeit nicht jede einzelne der zahlreichen Feinheiten, denn das führt schnell zu Problemen. Aus einer manuell verfassten WSDL-Datei generiert »Wsdl2Java« an der Konsole eine Java-Klasse. Sie dient als Einstieg, um den restlichen Code zu implementieren. Das Werkzeug ist Bestandteil fast aller oben genannten Framweworks für Webservices.
Java bringt Webserver mit
Das JDK 6 bietet eine integrierte Laufzeitumgebung für Webservices, die Anwender leicht aufsetzen. Die Server-Klasse in Listing 2 bietet hierbei nur eine »main()«-Methode zum Starten via Konsole und bindet den Service an einen bestimmten Endpoint. Dieser Endpoint enthält die Adresse, unter der der Service per HTTP zu erreichen ist. Beim Übersetzen generiert Java die notwendigen Klassen, um XML in Java-Methodenaufrufe umzuwandeln:
javac -d bin src/de/lm/wssample/server/*.java wsgen -cp bin -s src -d bin de.lm.wssample.server.KundenAnfrage
Weil er später eine WSDL-Datei benötigt, ruft der Programmierer »wsgen« mit der Option »-wsdl« auf:
wsgen -cp bin -s src -d bin -wsdl de.lm.wssample.server.KundenAnfrage
Für den Server startet der User einfach die Server-Klasse als Java–Applikation:
java -cp bin de.lm.wssample.server.Server
Um wie in Abbildung 4 zu kommunizieren, fehlt nun noch der Client.

Abbildung 4: Der Clientcode ruft Stubs auf, die sich mit der WS-Laufzeitumgebung verbinden. Diese überträgt Nachrichten per SOAP zum Server. Dort erreichen die Daten schließlich die Service-Implementation.
|
Listing 2: Implemenation des |
|---|
01 package de.lm.wssample.server;
02
03 import javax.xml.ws.Endpoint;
04
05 public class Server
06 {
07 /**
08 * Startet Server für den Kundenabfrage-Service
09 */
10 public static void main(String[] args)
11 {
12 KundenAnfrage service = new KundenAnfrage();
13 Endpoint endPoint = Endpoint.publish(
14 "http://localhost:8088/kundenanfrage", service);
15 }
16 }
|
WSDL gebiert Client
Das JDK 6 generiert auch Klassen, die die XML-Verwaltung und den Versand der Nachrichten kapseln. Um diese Stubs zu erzeugen, verbindet sich das Java-Programm »wsimport« zum Server und holt sich von dort die WSDL-Definitionen. Der vom Tool generierte Code für den Client besteht aus einer als Stub bezeichneten Java-Klasse (siehe Listing 3). Er lässt den Service-Aufruf wie eine lokale Methode aussehen. Entwickler sollten bedenken, dass sie eine Methode in einem entfernten System aufrufen. Daher müssen sie Verbindungsabbrüche und Timeouts einplanen.
|
Listing 3: Client-Stubs |
|---|
01 wsimport -p de.lm.wssample.client.generated 02 -keep -d bin 03 -s src http://localhost:8088/kundenanfrage?wsdl |
|
Listing 4: Service-Stubs |
|---|
01 package de.lm.wssample.client;
02
03 import de.lm.wssample.client.generated.KundenAnfrage;
04 import de.lm.wssample.client.generated.KundenAnfrageService;
05
06 public class ServiceClient {
07 public static void main(String[] args) {
08 KundenAnfrageService server =
09 new KundenAnfrageService();
10 KundenAnfrage svc =
11 server.getKundenAnfragePort();
12 System.out.println("Anfrage: " + args[0]);
13 String antwort = svc.stelleAnfrage(args[0]);
14 System.out.println("Antwort: " + antwort);
15 }
16 }
|
JAX-WS unterstützt ab Version 2.0 als Teil des JDK 6 sowohl den synchronen, also blockierenden, Aufruf, als auch den asynchronen Aufruf einer Service-Methode, der etwas mehr Code benötigt. Listing 4 implementiert einen Client, der den Webservice synchron aufruft.
Programmierer übersetzen ihn mit dem Compiler »javac« und starten ihn mit
javac -d ./bin -cp ./bin src/de/lm/wssample/client/ServiceClient.java java -cp bin de.lm.wssample.client.ServiceClient "Schneit es auf dem Mond?"
Der Clientcode ruft die Methode des Service-Stubs auf und erhält den Rückgabewert der Operation des entfernten Service. Der Webservice bearbeitet die Frage “Schneit es auf dem Mond?” und der Client gibt das Beispiel auf der Standardausgabe aus. Abbildung 5 zeigt alle verwendeten Dateien im Überblick.

Abbildung 5: Der Java-Code im Dateisystem als Eclipse-Projekt. Für das Beispiel reichte auch ein Vi.
Unter einem Dach
Das JDK 6 hilft Programmierern, schnell Webservices zu entwickeln. Es legt die Einstiegshürde so niedrig, weil es automatisch Code generiert und eine für Entwickler nützliche Laufzeitumgebung mitbringt. Dazu benötigen sie nur grundlegende Java-Kenntnisse.
Jedoch sollten Systemarchitekten bei Webservices beachten, dass sie entfernte Methoden aufrufen. Die sehen zwar in Java wie lokale Methoden aus, aber enthalten auch einige Stolperfallen wie Timeouts oder eine mangelnde Erreichbarkeit der Serveradresse. Für den produktiven Einsatz und gesteigerte Anforderungen ist ein Blick auf die erwähnten Webservice-Frameworks hilfreich.
An Webservices kommen Systementwickler in Unternehmen nur schwer vorbei. Trotz einiger Tücken haben sie sich als Quasi-Standard zur übergreifenden Kommunikation durchgesetzt. Der Umfang der Standards überwältigt auf den ersten Blick. Die Gremien begründen das damit, dass sie nicht nur für die Implemention, sondern auch als Spezifikation für Infrastruktur- und Werkzeughersteller vorgesehen sind. Anwender sollten die in den Profilen der WS-I festgelegten Standards und deren Werkzeuge nutzen. So steht dem Kontakt zweier Systeme über Webservices nichts im Wege. (mg)
|
Infos |
|---|
|
[1] Philipp Brnue, “Türöffner”, Linux-Magazin, 01/09, S. 44 [2] Webservices: [http://w3.org/2002/ws/] [3] Corba vs. Webservices:[http://www.ibm.com/developerworks/webservices/library/ws-arc3/] [4] SOAP: [http://w3.org/TR/soap12-part0/] [5] WSDL: [http://w3.org/TR/wsdl] [6] Webservices Interoperability Organization WS-I: [http://ws-i.org] [7] Axis2: [http://ws.apache.org/axis2/] [8] JAX-WS: [https://jax-ws.dev.java.net] |
|
Der Autor |
|---|
|
Guy Philipp Bollbach ist Software-Entwickler bei der Itemis GmbH. Schwerpunkte seiner Arbeit sind der WS-Todesstern und Unternehmensanwendungen. Er interessiert sich für Model Driven Software Development und weiche Faktoren des Projektalltags. Er veröffentlicht Fachartikel, spricht auf Konferenzen und arbeitet gerade an seinem ersten Buch. |







