18.15 Daily Soap
 
Für die Nutzung entfernter Ressourcen und zum Aufruf entfernter Methoden gibt es mehrere klassische Ansätze. Ein einfaches Verfahren ist die Anfrage mit Parametern an einen Web-Server, der den Inhalt zurückliefert. Zur Verteilung von Programmen haben sich CORBA, RPC, aber auch RMI bewährt. Der Weg über HTML hat den Vorteil, dass das Protokoll HTTP verbreitet ist, aber den Nachteil, dass kaum Möglichkeiten zur verteilten Programmierung gegeben sind. CORBA und RMI haftet der Nachteil an, dass ihre Kommunikation einen offenen Port erfordert, den Sicherheitsbeauftragte nicht unbedingt tolerieren. Zudem sind CORBA/RMI-Lösungen nicht wirklich einfach zu implementieren. Idealerweise verheiratet eine Technik beide Vorteile: HTTP-Kommunikation und objektorientierte Konzepte.
Bei den Firmen DevelopMentor, IBM, Lotus Development Corp., Microsoft und UserLand Software entstand das XML-basierte SOAP-Protokoll (bis Version 1.2 die Abkürzung für Simple Object Access Protocol). Es wird seit 1998 entwickelt und bietet einen einfachen Zugriff auf Server-Ressourcen mit den etablierten Web-Standards HTTP und XML. SOAP selbst beschreibt die Art und Weise, wie Inhalte (Serialisierung) und die XML-Daten übertragen werden. Die Übertragung selbst hat mit SOAP aber eigentlich nichts zu tun, denn dafür sind andere Protokolle definiert. HTTP ist ein ideales Transportprotokoll, da es für Web-Seiten in der Regel keine Beschränkungen von Firewalls gibt. Die beiden Kommunikationsparteien regeln mit SOAP so einen entfernten Methodenaufruf, der die Parameter und Ergebnisse in XML kodiert und überträgt. Durch die unabhängigen und anerkannten Web-Standards bietet SOAP gegenüber RMI oder CORBA und auch sonstigen Protokollen den Vorteil, nicht an eine Programmiersprache gebunden zu sein. Da Microsoft federführend bei der Spezifikation ist und das .NET-Framework seine Kommunikation vollständig auf SOAP aufbaut, wird es in der Zukunft eine Reihe von Java-Clients geben, die auf SOAP-Dienste anderer Anbieter wie Microsoft aufbauen. Die Übertragung kommt auch Sun mit ihrem Ziel einer betriebssystem- und plattformunabhängigen Schnittstelle entgegen.
Den Vorteilen stehen allerdings einige Nachteile gegenüber. Die XML-Repräsentation der Dokumente macht die Daten groß, und ein Parsen der Parameter und Ergebnisse auf beiden Seiten erforderlich. In Umgebungen, die performante Übertragung fordern – etwa bei der Kommunikation von mobilen Endgerät und Server –, wird sich SOAP nicht so schnell durchsetzen. Des Weiteren ist auch die Sicherheit von SOAP-Verbindungen noch nicht hinreichend gelöst. Ein Client könnte sich mit einem Server verbinden und einen Aufruf starten, obwohl die Berechtigung fehlt. Sicherheitseigenschaften müssten erst auf der Server-Seite implementiert werden. Die in Klartext übertragenen Nachrichten bilden ein weiteres Problem, das SSL jedoch verhindern kann.
Die technische Realisierung
Ein Client-Programm besorgt sich, wie bei entfernten Programmen üblich, eine Referenz auf das entfernte Objekt. Das ist eine URL auf einen RPC-Router. Dieser Router wird mittels einer normalen HTTP- POST-Anfrage aktiviert. Er bekommt über den Client eine XML-kodierte Nachricht (Content-Typ ist einfach text/html), in der die aufzurufende Methode und ihre Parameter kodiert sind. Der RPC-Router nimmt diese Nachricht entgegen, parst das empfangene XML-Dokument und leitet die Anfrage an die Methode weiter. Diese produziert die Ausgabe, die wiederum als XML-Dokument über die Antwort vom Server zum Client geschickt wird. Der Client nimmt das Ergebnis entgegen, und die Kommunikation ist beendet.
SOAP bietet für entfernte Methodenaufrufe einige Standarddatentypen an. Zu diesen gehören einfache Datentypen wie Ganzzahlen, Fließkommazahlen, Zeit- und Datumsangaben und Binärdaten. Außerdem unterstützt SOAP zusammengesetzte Datentypen wie Strukturen und Arrays. Wie diese Daten nun tatsächlich in eine XML-Nachricht umgesetzt werden, müssen wir glücklicherweise nicht wissen. Als Endanwender kommen wir mit der Nachricht nicht in Kontakt.
18.15.1 SOAP-Implementierungen
 
SOAP ist nur ein Standard zum Austausch von Daten, aber keine Programmier-API. Für unterschiedliche Programmiersprachen gibt es Implementierungen, und auch für Java gleich mehrere. Zwei sind populär:
|
Apache Axis (Apache EXtensible Interaction System) unter http://ws.apache.org/axis/java/index.html. Apache Axis ist der Nachfolger von Apache Soap. (Ob eine Applikation Apache Soap oder Axis nutzt, ist gut an den Versionsnummern zu erkennen. Die letzte Apache Soap Version war 2.3.1, während die aktuelle Axis-Version 1.2 ist.1
) |
|
JAX-WS 2.0 (Java API for XML Web Services) – früher JAX-RPC 2.0 – von Sun. Dazu kommt die SOAP with Attachments API for Java (SAAJ), die nicht wie JAX-WS die entfernten Aufrufe in den Mittelpunkt stellt, sondern den Nachrichtenaspekt. |
Apache Axis ist leicht zu verwenden und wird im Folgenden vorgestellt. Für die Sun-API bietet das »The J2EE 1.4 Tutorial« (http://java.sun.com/j2ee/1.4/docs/tutorial/doc/) einen ersten Überblick mit Beispielen.
SOAP-Implementierung der Apache-Gruppe
Für unsere Zwecke wollen wir die Datei axis-bin-1_2_1.zip vom Indianer-Server http://www.apache.de/dist/ws/axis/1_2_1/ beziehen und auspacken. Im Archiv finden sich unter lib/ einige Java-Archive, die wir alle – bis auf axis-ant.jar – in unseren Klassenpfad aufnehmen müssen. Um Warnungen zu vermeiden, sollten wir auch mail.jar und activation.jar in den Pfad aufnehmen und log4j.properties mit zu unseren Quellen in das Default-Paket nehmen.
18.15.2 Einen Client mit der Apache-Bibliothek implementieren
 
Bevor wir uns der Arbeitsweise des Servers nähern, wollen wir uns einen vorhandenen Dienst zunutze machen. Viele freie Dienste sind unter http://www.xmethods.com/ aufgelistet. Der Dienst, den wir in unserem ersten Beispiel nutzen wollen, ist gerade zur Weihnachtszeit besonders hilfreich. Seine Aufgabe ist es, zu einem Tannenbaum bestimmter Größe und mit gegebenem Radius die Anzahl von Glühbirnen zu berechnen, die der Baum tragen kann. Unter http://soap.fmui.de/webservices.php#ChristmasTree ist der Dienst näher beschrieben. Als zusätzliche Größe muss der Abstand der Kerzen angegeben werden. Die Parameter sind vom Typ double und tragen die Namen h (Höhe), r (Radius), l (Lichtabstand).
Unser SOAP-Programm muss zunächst die entsprechenden Klassen beziehungsweise Schnittstellen einbinden. Da wir es hier mit Schnittstellen-orientierter Programmierung zu tun haben, handelt es sich bei allem außer der zentralen Klasse org.apache.axis.client. Service aus dem Axis-Paket um Schnittstellen aus javax.xml.
Listing 18.5
com/lang/java/insel/soap/HowManyLamps.java
package com.lang.java.insel.soap;
import java.rmi.RemoteException;
import javax.xml.namespace.QName;
import javax.xml.rpc.Call;
//import javax.xml.rpc.ParameterMode;
import javax.xml.rpc.ServiceException;
//import javax.xml.rpc.encoding.XMLType;
import org.apache.axis.client.Service;
public class CopyOfHowManyLamps
{
public static void main( String[] args )
{
Jeder Dienst ist hier durch mehrere Parameter gekennzeichnet. Einer davon ist die URL des Servers, ein anderer der Name des Dienstes. Beginnen wir mit dem Aufbau der Methoden- und Parameterbeschreibung. Einem Objekt vom Typ Call werden dabei die Informationen übergeben. Später wird dieses Call-Objekt auch die invoke()-Methode anbieten, die den Aufruf tatsächlich durchführt.
try
{
Service service = new Service();
Call call = service.createCall();
call.setTargetEndpointAddress( "http://soap.fmui.de/RPC" );
call.setOperationName( new QName("urn:christmas", "ChristmasTree" ) );
Der Dienst trägt den Service-Namen christmas; durch den Namensraum ergibt sich »urn:christmas«. Die aufzurufende Methode heißt ChristmasTree.
Optional können wir im Folgenden die Parametertypen und den Rückgabetyp genauer spezifizieren.
// call.addParameter( "h", XMLType.XSD_DOUBLE, ParameterMode.IN );
// call.addParameter( "r", XMLType.XSD_DOUBLE, ParameterMode.IN );
// call.addParameter( "l", XMLType.XSD_DOUBLE, ParameterMode.IN );
//
// call.setReturnType( XMLType.XSD_LONG );
Der nächste Schritt ist der Aufruf der Methode. Wir fangen noch Fehler ab, und das Programm ist abgeschlossen.
Object ret = call.invoke(
new Object[] { new Double(200), new Double(100), new Double(10) } );
System.out.println( ret ); // 277
}
catch ( ServiceException e )
{
e.printStackTrace();
}
catch ( RemoteException e )
{
e.printStackTrace();
}
}
}
18.15.3 Der Seifen-Server
 
Ein SOAP-Server muss die Anfragen entgegennehmen und eine Methode aufrufen. Von der Apache-Gruppe gibt es einen entsprechenden Server, der als Servlet realisiert ist. Das Servlet übernimmt dabei die Aufgabe des Routers, der die XML-Anfragen entgegennimmt und auswertet. Die Installation ist einfach. In dem schon erwähnten axis-bin-1_2_1.zip-Archiv befindet sich ein Webapps-Verzeichnis namens axis. Dieses Verzeichnis wollen wir in das webapps-Verzeichnis des Tomcat-Servers legen. Wenn wir Tomcat anschließend starten, erkennt er die neue Webapplikation und wird dann in einem Browser die URL http://localhost:8080/soap/index.html eingeben, verkündet die generierte Web-Seite den Erfolg. Weitergehende Installationshinweise gibt die Axis-Web-Seite.
Wir wollen hier nicht näher auf die Implementierung auf der Server-Seite eingehen. Im Prinzip ist noch eine Beschreibungsdatei für den Dienst anzulegen, beim Server einzutragen, und die Java-Klassen für den Server-Dienst sind zu implementieren.
1 Zur Konvertierung siehe auch http://www.java-tutor.com/go/soap2axis.
|