Java RMI und SOAP

Werbung
RMI und SOAP für Java – Seminar-Arbeit von Marc Wodischek und Timo Holzherr
Software-Engineering-Projekt
Berufsakademie Horb
Studiengang Informationstechnik
Java RMI und SOAP
Timo Holzherr, Marc Wodischek
IT2003
BA - Horb
Florianstraße 15
72160 Horb a. N.
[email protected]
[email protected]
Betreuender Dozent:
Prof. Dr.-Ing. Olaf Herden
Dezember 2005
1
RMI und SOAP für Java – Seminar-Arbeit von Marc Wodischek und Timo Holzherr
Abstract
In der Folgenden Arbeit werden Grundlagen, Vorgehensweisen in der Verwendung
sowie Implementierung von RMI 1 bzw. SOAP 2 , der Programmiersprache Java
erläutert. Dies geschieht mit Hilfe eines Beispielprogramms. Dieses
Beispielprogramm ist ein Online-Spiel, das an klassische „Battleship“ (Schiffe
versenken) - Spiel erinnern soll. Mithilfe dieses Spieles werden die Technologien
sowie deren Implementierung erklärt und die theoretischen Grundkenntnisse
verständlich illustriert.
Auf die Implementierung des Spieles, dessen Algorithmen und den Aufbau des
Applets, mit der Grafischen Benutzeroberfläche wird nur eingegangen, falls dies
zum Verständnis der themenbezogenen Programmteile erforderlich ist.
1
2
Remote Method Invocation (Erklärung s. Abschnitt 1)
Simple Object Access Protocol (Erklärung s. Abschnitt 6)
2
RMI und SOAP für Java – Seminar-Arbeit von Marc Wodischek und Timo Holzherr
Inhaltsverzeichnis
Java RMI und SOAP......................................................................................................... 1
Abstract............................................................................................................................. 2
Inhaltsverzeichnis ............................................................................................................. 3
1
Einleitung.................................................................................................................. 4
2
Nutzen von entfernten Zugriffen / Aufrufen ............................................................. 5
2.1.1
2.2
Das RMI Protokoll.............................................................................................. 6
2.3
Allgemeine Probleme ......................................................................................... 7
2.3.1
Netzwerkbasierende Probleme.................................................................. 7
2.3.2
Speicherbasierende Probleme ................................................................... 8
2.4
Entfernte Objekte allgemein ............................................................................... 8
2.4.1
3
4
Java RMI (Remote Method Invocation).................................................... 5
Entfernte Schnittstellen definieren ............................................................ 9
Entfernte Objekte implementieren mit JAVA-RMI................................................ 10
3.1
Aufbau und Besonderheiten bei der Implementierung ..................................... 10
3.2
Entfernte Methoden implementieren ................................................................ 11
3.3
Serialisierung .................................................................................................... 11
3.4
der DistributedGC............................................................................................. 13
SOAP ...................................................................................................................... 14
4.1
Einleitung ......................................................................................................... 14
4.2
Aufbau und Ablauf eines SOAP-Methodenaufrufes ........................................ 15
4.3
SOAP-Implementierungen ............................................................................... 16
4.3.1
Clientseitige SOAP-Programmierung ..................................................... 17
4.3.2
Serverseitige SOAP-Programmierung .................................................... 19
5
Fazit ........................................................................................................................ 21
6
Literaturverzeichnis ................................................................................................ 21
3
RMI und SOAP für Java – Seminar-Arbeit von Marc Wodischek und Timo Holzherr
1
Einleitung
Aufgrund der rasanten Entwicklung auf dem Computermarkt in Bezug auf
Geschwindigkeit, Ressourcen, Bedienbarkeit (Usability), Preis und vor allem steigender
Kenntnis von Anwendern, hat sich auch die Art der Verwendung stark verändert.
Waren früher Computer nur etwas für Institute mit wissenschaftlichem oder
militärischem Hintergrund, so zeigte sich schnell ein Trend in Richtung „Personal
Computer“ („PC“). Die Komponenten wurden für den Massenmarkt hergestellt und
somit billiger. Programme wurden auf benutzerfreundliche Bedienung ausgelegt und es
wurde stark zwischen Server oder Supercomputer und Personal Computer in Hinsicht
auf Entwicklung unterschieden.
So wurde auch die Arbeitsweise mit dem Computer verändert. War es zu Beginn noch
eine große Rechenmaschine, die Arbeit für eine ganze Abteilung übernahm, da nicht
jeder Mitarbeiter einen Computer hatte, so wurde dies in den letzten Jahren so verändert,
dass nun jeder Mitarbeiter oder auch jedes Familienmitglied seinen eigenen Computer
hat, da dieser stark genug wurde um alle Aufgaben, die der Benutzer hat, gut ausführen
zu können.
Nun
kommen
wir
mit
Dual-Core 1
Prozessoren,
neuen
verbesserten
Prozessorarchitekturen mit mehreren ALUs 2 , größeren Speichern, kleineren Strukturen,
geringerem Stromverbrauch und der Rechenleistung in neue Dimensionen. Dies und
verbesserte Netzwerkarchitekturen mit höherer Bandbreite sowie moderne
Betriebssysteme mit echter Multiuser Unterstützung oder auch Funktionen wie „Remote
Desktop“ erwirken einen weiteren Wandel in der Verwendung von Computern.
Es wird nun ein weiterer Schritt eingeführt, dass ein sehr leistungsfähiger PC zur
Verfügung steht, auf den alle Benutzer zugreifen können und so von seiner
Rechenleistung profitieren. Ein weiterer Vorteil ist, dass auch Daten aller Anwender
lokal für alle zugreifbar gespeichert werden können. Benötigt werden nun jedoch
Technologien, wie „Remote Desktop“, oder Multiuser Fähigkeit von Betriebssystemen
um es den Benutzern zu ermöglichen über externe Verbindungen den Computer zu
nutzen. Sun stellt Java mit RMI/SOAP genau solche Technologien zur Verfügung, die
entfernte
Zugriffe
auf
Methoden
oder
Funktionen
nutzen.
1
Als Dual-Core-Prozessor (Doppelkernprozessor) bezeichnet man einen Multi-Core-Prozessor mit genau
zwei Hauptprozessoren. Als Multi-Core-Prozessor (auch: Mehrkernprozessor oder Multikernprozessor),
bezeichnet man einen Mikroprozessor mit mehr als einem vollständigen Hauptprozessor.
2
Eine Arithmetic Logical Unit (ALU, zu deutsch arithmetisch-logische Einheit) ist ein elektronisches
Rechenwerk, welches in Prozessoren zum Einsatz kommt.
4
RMI und SOAP für Java – Seminar-Arbeit von Marc Wodischek und Timo Holzherr
2
Nutzen von entfernten Zugriffen / Aufrufen
Um die Funktion von RMI so gut wie möglich zu erklären sollte ein Beispiel auf der
Tatsache der neuen Art der Benutzung von Computern, wie auch schon in der Einleitung
beschrieben, aufgebaut werden.
Denkt man an Aufgabengebiete, bei denen Supercomputer immer noch nötig sind, so
fällt schnell das Beispiel der Simulationen ein. Simulationen werden in einem breiten
Bereich der Forschung und Entwicklung eingesetzt. Sie sollen immer präziser werden
und sind dies auch geworden. Dies benötigt jedoch Rechenleistung. Rechenleistung, die
ein „Personal Computer“ wie ihn der Mitarbeiter / Forscher besitzt, nicht zur Verfügung
stellen kann. Man will jedoch nicht den starken Simulationscomputer besetzten während
man mit Implementierung und ähnlichem beschäftigt ist. So wäre es das Beste man
könnte auf dem eigenen Laptop die Vorarbeit leisten und später die Berechnung vom
Simulationscomputer durchführen lassen. Genau dies ist Sinn und Zweck der Remote
Method Invocation 1 „RMI“.
2.1.1
Java RMI (Remote Method Invocation)
Verwenden wir nun das Beispiel von der Simulation weiter um Java RMI zu erklären.
Um in Programmen die Leistungsfähigkeit des Simulationsrechners nutzen zu können
wäre es perfekt, wenn die komplizierte, rechenaufwändige Funktion auf diesem
Computer laufen würde. Das Programm soll jedoch mit grafischer Oberfläche und
Eingabeparametern dem Benutzer auf dessen PC zur Verfügung stehen.
Man sollte also die Server-Funktionen wie lokale Funktionen aussehen lassen. Ein
solches Modell, haben Birrel und Nelson bereits 1984 vorgestellt.
(Quelle: Java ist auch eine Insel.)
In unserem Beispiel wäre es nun so, dass der Benutzer eine Funktion aufruft, z.B.
plot(crash_simulation(parameter1,parameter2));
Diese sich jedoch auf dem Server befindet und auch dort verarbeitet wird:
double crash_simulation(double param1 , double param2)
{
//Komplizierte Berechnung Differentialgleichungen viele for - Schleifen usw.…
}
Wichtig ist nun noch die Verbindung zwischen Client und Server. Im Normalfall spricht
der Client nicht direkt mit dem Server, sondern über Stellvertreterobjekte (engl. Proxies).
Über diese Proxies wird die Verbindung aufgebaut. Für den Client sieht diese Funktion
wie eine Serverfunktion aus, dabei verpackt sie die Informationen und sendet diese an
den Server weiter. Daher wird die Implementiereung des Aufrufs der
Simulationsfunktion crash_simulation() auf Client Seite eher so aussehen:
1
Aufruf von entfernten Methoden (remote = entfernt , Method = Methode , invocation = Aufruf)
5
RMI und SOAP für Java – Seminar-Arbeit von Marc Wodischek und Timo Holzherr
double crash_simulation(double param1 , double param2)
{
// Verbindung aufbauen
// die Parameter übernehmen und an den Server schicken ( „write(param1 , param2)“)
// Auf das Ergebnis warten und…
// Ergebnis Ausgeben.“ plot(Ergebnis);“
}
Abbildung 1: Unterschiede zwischen Verbindung mit und ohne Proxy. (Quelle: http://publib.boulder.ibm.com)
Der Verbindungsaufbau kann über Sockets 1 geschehen. Hier ist ein bestimmter Ablauf
programmiert. Der Server wartet auf Anfragen von Clients. Dann entnimmt er aus dem
gesendeten Paket seine Aufgaben und ruft seine dazu passende Funktion auf.
2.2
Das RMI Protokoll
RMI in Java (
aufzurufen.
) ist die Technologie um entfernte Objekte und deren Methoden
Ähnlich wie beim OSI 2 - Schichten - Modell verwendet RMI auch verschiedene
Abstraktionsebenen.
1
Ein Socket (wörtlich übersetzt "Sockel" oder "Steckverbindungen") ist eine bi-direktionale SoftwareSchnittstelle zur Interprozess- (IPC) oder Netzwerk-Kommunikation.
2
Das OSI-Modell (engl. Open Systems Interconnection Reference Model) ist ein offenes Schichtenmodell für
die Kommunikation informationsverarbeitender Systeme. Es handelt sich um vereinheitlichte Verfahren und
Regeln für den Austausch von Daten.
6
RMI und SOAP für Java – Seminar-Arbeit von Marc Wodischek und Timo Holzherr
Sockets sind wie bereits angesprochen eine Lösung für den Verbindungsaufbau. Es ist
jedoch auch möglich, die Übermittlung der Daten mittels http - Anfragen zu steuern.
Auch verschlüsselte Verbindungen über SSL 1 sind denkbar oder auch Verbindung über
UDP 2 . All diese Protokolle sind zusammengefasst unter dem Begriff „RMI Wire
Protocol“.
Abbildung 2: Architektur von RMI
2.3
Allgemeine Probleme
Während RMI eine Lösung für das Problem der entfernten Aufrufe liefert, gibt es einige
Probleme, die nicht nur durch Software gelöst werden können.
2.3.1
Netzwerkbasierende Probleme
Ein
grundlegendes
Problem
ist
die
allgemeine
Bereitstellung
eines
Kommunikationssystems. Doch ein Kommunikationssystem löst nicht alle Probleme
einer Verbindung. Es muss sichergestellt werden, dass die Verbindung auch immer
vorhanden ist, oder dass die Daten in einwandfreiem Zustand ankommen.
Da beide Rechner physikalisch voneinander getrennt sind und dadurch verschiedene
Lebenszyklen haben, kann nicht immer garantiert werden, dass eine Kommunikation
möglich ist. Ist der Server aufgrund verschiedener Einwirkungen nicht erreichbar, so
muss dies der Client erkennen und darauf reagieren. Hier können nur typische
Vorgehensweisen verwendet werden wie z.B. über einen Zeitablauf (Timeout) zu gehen.
1
Transport Layer Security (TLS) oder Secure Sockets Layer (SSL) ist ein Verschlüsselungsprotokoll für
Datenübertragungen im Internet.
2
Das User Datagram Protocol (UDP) ist ein minimales, verbindungsloses Netzprotokoll. Es gehört zur
Transportschicht der TCP/IP-Protokollfamilie und ist im Gegensatz zu TCP nicht auf Zuverlässigkeit
ausgelegt.
7
RMI und SOAP für Java – Seminar-Arbeit von Marc Wodischek und Timo Holzherr
Zudem ist die Zeit ein kritischer Faktor. Da bei entfernten Verbindungen die
Abarbeitungszyklen deutlich höher sind als bei lokalen Aufrufen, muss das Abarbeiten
zeitkritisch beobachtet werden. Die zeitlichen Probleme kommen vor allem von der
Verbindung über Netzwerke wie von zusätzlichen Implementierungen, die einen
entfernten Aufruf erst ermöglichen z.B. Proxy Aufbau und Verbindung über Sockets.
Hier muss wie beschrieben jede Aufgabe in Anfragen verpackt werden.
2.3.2
Speicherbasierende Probleme
Wie schon angesprochen ist eine Hauptursache für Probleme mit entfernten Zugriffen
und Aufrufen die physikalische Trennung der zwei Geräte. So haben die beiden Rechner
verschiedene Laufzeiten mit verschiedenen Prozessoren und vor allem verschiedenem
Speicher.
Wichtig ist es die Zugriffe exklusiv erfolgen zu lassen, da sonst Änderungen des
Benutzers verloren gehen könnten. Werden beim Benutzer Änderungen vorgenommen,
so werden sich diese nicht auf die Referenz des Objektes, mit der, der Server arbeitet,
übernommen. Werden die Daten nun vom Server zurückgespielt, werden die
Änderungen überschrieben.
Somit wird deutlich, dass normale Referenzen nicht ausreichen. Große, umfangreiche
Objekte müssen öfter serialisiert werden. Das Problem dabei ist jedoch, dass nicht alle
Objekte serialisierbar sind. Vor allem Systemklassen können nicht einfach übertragen
und serialisieren.
2.4
Entfernte Objekte allgemein
Der Begriff Middleware bezeichnet in der Informatik im Allgemeinen eine Schicht
zwischen zwei Prozessen. Einerseits um die Komplexität der jeweilig anderen Seite zu
verbergen, oder um eine einfach zu implementierende eindeutig definierte Schnittstelle
zwischen den Prozessen zu liefern. Somit wird die Kopplung zweier Systeme entzerrt.
Es ist eine Zwischenschicht und ist wie der Server für den Client und der Client für den
Server, obwohl keine direkte Verbindung besteht.
Es kommuniziert sozusagen die Middleware mit dem Server und mit dem Client und
stellt somit die Verbindung her. Ein weiteres Einsatzgebiet ist die Trennung zwischen
Datenbank und Benutzerprogramm. Das Benutzerprogramm ist nicht direkt mit der
Datenbank verbunden, sondern gibt seine Anfragen an die Middleware weiter, die dann
die Ergebnisse von der Datenbank abholt, um Sie dann dem Benutzerprogramm wieder
zugänglich zu machen.
Ein großer Vorteil ist, dass zum Beispiel die Anbindung der Datenbank zur Middleware
verbessert werden kann, ohne dass der Benutzer ein Update seines Programms benötigt.
8
RMI und SOAP für Java – Seminar-Arbeit von Marc Wodischek und Timo Holzherr
2.4.1
Entfernte Schnittstellen definieren
Wie bereits erwähnt, wird die Verbindung über eine Art Middleware vorgenommen.
Will der Benutzer nun also Methoden nutzen, muss er die Middleware, also ein
Stellvertreterobjekt befragen, welches die Daten nun für ihn verwaltet. Das heißt, es
packt die Daten ein und übermittelt sie. Diese Hilfsfunktionen werden automatisch
generiert. Sie müssen jedoch definiert werden, um passenden Quellcode für die
Übertragung zu erzeugen. Bei Java RMI ist dies die Definition eines Interface mit den
benötigten Methoden, z.B.:
import
import
import
import
java.io.Serializable;
java.rmi.Remote;
java.rmi.RemoteException;
java.util.Vector;
public interface ReceiveMessageInterface extends Remote, Serializable
{
void startGame(Game game) throws RemoteException;
//…usw. …
}
Diese Implementierung in unserem Spiel, zeigt die wichtigsten Eigenschaften der
Schnittstelle:
-
Die eigene Schnittstelle erbt von der Schnittstelle „Remote“ und erweitert
diese. Dies ist nötig, da nur Klassen, die von Remote erben, entfernte
Methoden anbieten können. Remote ist ein „leeres“ Interface, es sind also
keine Methoden vorgegeben, die implementiert werden müssen.
-
Jede „Remote“ - Methode muss die Anweisung „throws RemoteException“
besitzen, da die angegebenen Methoden nicht beabsichtigte Fehler auslösen
können.
9
RMI und SOAP für Java – Seminar-Arbeit von Marc Wodischek und Timo Holzherr
3
Entfernte Objekte implementieren mit JAVA-RMI
3.1
Aufbau und Besonderheiten bei der Implementierung
Der Server ist ein wichtiger Bestandteil und der Client muss über den Stellvertreter mit
ihm kommunizieren können. Er muss einige Vorgaben erfüllen, damit die Verbindung
zustande kommen kann.
Er muss die entfernte Schnittstelle implementieren, einen speziellen Konstruktor
besitzen und eine Klasse erweitern.
Implementiert sieht die Klasse RMIServer folgendermaßen aus. :
public class RmiServer extends
UnicastRemoteObject implements ReceiveMessageInterface
{
public static void main(String args[])
{
try
{
int port=3232;
if((args!=null) && (args.length>0) && (args[0]!=null))
{
try
{
port=new Integer(args[0]).intValue();
}
catch(NumberFormatException nfe)
{
System.err.println("Falscher Port!“);
}
}
new RmiServer(port);
}
catch (Exception e)
{
e.printStackTrace();
System.exit(1);
}
}
public RmiServer(int port) throws RemoteException
{
registry = LocateRegistry.createRegistry( thisPort );
registry.rebind("rmiServer", this);
System.out.println("RMI-Server gestartet”);
}
}
10
RMI und SOAP für Java – Seminar-Arbeit von Marc Wodischek und Timo Holzherr
Wie bereits erwähnt, muss unsere RMIServer Klasse eine andere Klasse erweitern. Diese
ist die „UnicastRemoteObject“ - Klasse aus dem Java – RMI – Paket. Durch die
Methoden, die RMIServer.java von UnicastRemoteObject erbt, wird eine Übertragung
von Daten über ein Standard-TCP/IP Socket ermöglicht.
Wie man erkennt ist auch der Konstruktor in RMIServer.java kein Standardkonstruktor.
Er hat zwei spezielle Eigenschaften.
Von der Deklaration her ist er ein Standardkonstruktor. Er ruft jedoch automatisch den
Konstruktor der Oberklasse, also von UnicastRemoteObject, auf.
Es besteht bei der Implementierung des Servers jedoch auch ein Problem:
Es kann sein, dass entfernte Klassen schon von einer anderen Klasse erben, und somit
gegen die Mehrfachvererbung verstoßen würden. In diesem Fall, muss die
implementierende Klasse ausgelagert werden.
3.2
Entfernte Methoden implementieren
Entfernte Methoden werden wie alle anderen Methoden implementiert. Es ist jedoch
wichtig die RemoteException zu werfen, falls ein Verbindungsfehler oder ähnliches
eintritt.
public void startGame(Game game) throws RemoteException
{
… game.start();
}
3.3
Serialisierung
Ein Hauptpunkt bei Java RMI ist die Serialisierung.
Die Besonderheit ist, wie bereits erwähnt, dass bei den entfernten Aufrufen nicht
spezielle Zeichenketten als Art Protokoll übergeben werden, sondern komplette Objekte.
Um auf die Klassen/Objekte und deren Methoden zugreifen zu können, müssen diese bei
Namensdiensten angemeldet sein.
Dies nennt man Serialisierung der Klassen. Es gibt hierfür in Java zwei Möglichkeiten.
Einmal über die Methode Naming und über die Methode Registry.
11
RMI und SOAP für Java – Seminar-Arbeit von Marc Wodischek und Timo Holzherr
Mithilfe dieser Methoden wird der zu verwendende Port angegeben und dann einmal auf
Serverseite das Objekt bekannt gemacht. Das heißt, das Objekt bekommt einen Namen
unter dem der Client es finden kann. Dem Client muss ebenfalls gesagt werden, welchen
Port er verwenden soll. Er legt nun das Objekt an, damit er es wie einen normalen Aufruf
im weiteren Programm verwenden kann. Die Implementierung ist im Codebaispiel auf
Seite 9 zu sehen. Der Aufruf der Methode bzw. wie das Objekt nun weiter verwendet
wird, ist im Codebeispiel auf Seite 10 ersichtlich.
Die mit der Naming Methode verbundene Syntax, hat immer wieder einige Befehle
gemein, die kurz erwähnt werden sollen:
- Bind/Unbind (Serverseitig zu An/Abmeldung des Objektes)
- Lookup (Clientseitig um nach dem Server-Objekt „Ausschau“ zu halten)
12
RMI und SOAP für Java – Seminar-Arbeit von Marc Wodischek und Timo Holzherr
3.4
der DistributedGC
Da die Lebensdauer entfernter Objekte nicht genau festgelegt und überprüft werden
kann, kommen spezielle Anforderungen an den “Garbage Collector”(GC) 1 der JVM 2
hinzu.
Im normalen Betrieb weiß der GC immer, wann Objekte referenziert und wieder
dereferenziert werden. Somit kann er einfach die fälligen Speicherbereiche wieder
leeren. Im entfernten Aufruf ist dies jedoch nicht möglich. Daher muss über einen
zusätzlichen Mechanismus klargestellt werden, wann die Objekte referenziert und
wieder dereferenziert werden. Es werden also referenced-flags beim Nutzen der
Verbindung mitgeliefert. Genauso ein dereferenced flag beim Lösen der Verbindung.
Die Klasse bleibt bis zum endgültigen Löschen aus dem Speicher jedoch noch einige
Zeit auf dem Server erhalten.
Man kann diese Verweildauer auch explizit angeben.
Bsp: java –Djava.rmi.dcg.leaseValue=30 MyClass
1
Automatische Speicherbereinigung oder Garbage-Collection (GC) (auch Freispeichersammlung) ist ein
Verfahren zur regelmäßigen automatischen Wiederverfügbarmachung von nicht mehr benötigtem Speicher und
anderen Betriebsmitteln, indem nicht mehr erreichbare Objekte im Speicher automatisch freigegeben werden.
2
Die Java Virtual Machine (abgekürzt Java VM oder JVM) ist eine Laufzeitumgebung und virtuelle Maschine
für Software. Die Java Virtual Machine führt den so genannten Java-Bytecode aus und kann als Pendant zur
Common Language Runtime bei Microsoft .NET gesehen werden.
13
RMI und SOAP für Java – Seminar-Arbeit von Marc Wodischek und Timo Holzherr
4
4.1
SOAP
Einleitung
Es gibt verschiedene Ansätze, entfernte Methodenaufrufe auszuführen. Das oben bereits
erwähnte Verfahren RMI ist eines davon. Der Nachteil dieser Kommunikation ist jedoch,
dass sich diese Applikation an einen TCP/IP - Port bindet, was oft eher als
sicherheitstechnisch bedenklich eingestuft wird. Viele Firewalls und Proxy-Server
erlauben zudem oft nur eine Netzwerk-Kommunikation über den TCP-Port 80 (HTTP 1 ).
Aus diesem Grund ist oft ein Verfahren, Daten zu übertragen, nötig, welches die
Informationen über Port 80 bezieht und sendet.
Eine sehr einfache Realisierung dieser Aufgabe könnte man durch dynamische
Webseiten (mit PHP o.ä. erstellt) erreichen. Die Webseiten werden aufgerufen und
bekommen die benötigten Informationen beispielsweise im Post-Header übertragen.
Darauf kann das serverseitige Skript reagieren und entsprechende Ausgaben an den
Client zurückgeben.
Dies wäre jedoch eine sehr „einfache“ Lösung und hat kaum objektorientierten
Charakter. Die Übertragenen Daten können nur aus Strings bestehen, bieten also nicht
wie RMI die Möglichkeit bequem Objekte zu übertragen.
Diesen Vorteil vereinigt SOAP mit dem Vorteil, über das HTTP-Protokoll Daten zu
übertragen.
SOAP steht für Simple Object Access Protocol und wird seit 1998 entwickelt. Die
Firmen, die sich bei der Entwicklung dieses Protokolls anfänglich beteiligten waren, sind
DevelopMentor, IBM, Lotus Development Corp., Microsoft und UserLand Software.
Das Protokoll ist XML-basiert und beschreibt die Art und Weise, wie Inhalte
(Serialisierung 2 ) und die XML-Daten übertragen werden. Die Übertragung selbst regelt
SOAP nicht. Dafür wird meist das HTTP-Protokoll verwendet. Durch SOAP wird der
entfernte Methodenaufruf geregelt und ausgeführt. Dabei übergibt der Aufrufende
Parameter, die in Form einer XML-Struktur an den verarbeitenden
Kommunikationspartner weitergegeben werden. Dieser liefert dem aufrufendem ClientProgramm wiederum die Rückgabewerte der Methode in Form einer XML-Struktur
zurück.
Wie man schon anhand der Beschreibung des Übertragungsweges von SOAP erkennen
kann, ist die SOAP-Architektur im Vergleich zu RMI o.ä. sehr flexibel und damit
programmiersprachen- und plattformunabhängig. Das Framework von .NET baut
vollkommen auf eine Kommunikation mit SOAP auf.
1
Das Hypertext Transfer Protocol (HTTP) ist ein zustandsloses Protokoll zur Übertragung von Daten.
Zugeordnet ist dabei die Anwendungsschicht. Diese entspricht im ISO/OSI-Modell der Schicht 7, im
üblicherweise im Internet verwendeten TCP/IP-Referenzmodell dagegen der Schicht 5. Primär wird es im
Rahmen des World Wide Web zur Übertragung von Webseiten verwendet (Webbrowser greifen fast
ausschließlich mit diesem Protokoll auf Web-Server zu).
2
Man versteht darunter eine sequentielle Abbildung von Objekten auf eine externe Darstellungsform, um diese
beispielsweise zu übertragen
14
RMI und SOAP für Java – Seminar-Arbeit von Marc Wodischek und Timo Holzherr
An seine Grenzen stößt die SOAP-Architektur jedoch bei Umgebungen, welche eine
performante Übertragung erfordern. Ein Beispiel hierfür kann die Kommunikation eines
mobilen Endgerätes und einem Server sein. Auch in der Maschinensteuerung müssen
Daten in Echtzeit übertragen werden. Hierfür ist SOAP bisher nicht geeignet. Der Grund
hierfür ist, dass die XML-Repräsentation der Objekte und Strukturen die Daten sehr groß
(ca. Faktor 25 beim Request und Faktor >500 bei der Antwort) macht. Dies beansprucht
die Netzwerkbandbreite sehr stark. Zudem erfordert das Parsen der Strukturen
zusätzliche Rechenleistung, welche vor allem im mobilen Clientbereich nicht immer
ausreichend zur Verfügung steht.
Da HTTP ein zustandsloses Protokoll 1 ist, sind Sicherheitsaspekte meist nicht
ausreichend gewährleistet. Ein Client könnte sich mit einem Server verbinden und einen
Aufruf starten, obwohl die Berechtigung fehlt. Beim Entwerfen von SOAPArchitekturen muss man stets diesen Aspekt mitbetrachten.
4.2
Aufbau und Ablauf eines SOAP-Methodenaufrufes
Das Client-Programm benötigt eine Referenz auf den entfernten Server. Diese Referenz
ist bei SOAP eine URL auf einen RPC-Router. Der Client sendet ein HTTP-POSTRequest an den HTTP-Server. In den Daten sind in Form einer XML-Struktur (siehe
unten) der Name und die Parameter der aufzurufenden Methode beinhaltet.
Im nachfolgenden Beispiel ist ein Methodenaufruf dargestellt, der Kreditkartendaten
überprüfen soll. Als Parameter erwartet die Methode zwei Strings. Zum einen eine
Kreditkartennummer (entspricht <number>) und zum Anderen das Gültigkeitsdatum der
Karte (entspricht <valid>). Der Name der Methode, die aufgerufen werden soll, wird in
…xmlns:ns1="urn:CardValidator"… festgelegt.
Der RPC-Router empfängt diese Informationen und parst die XML-Struktur. Daraufhin
wird die im Aufruf angegebene Methode mit den Parametern aufgerufen. Diese Methode
berechnet ihr Ergebnis und gibt die Informationen, die an den Client zurückgesendet
werden müssen, über den Server an den Client in Form einer XML-Struktur (siehe
Beispiel weiter unten) zurück.
(Rückgabe erfolgt im Tag <addReturn
xsi:type="xsd:string">true</addReturn>)
Die Client-Software nimmt das Ergebnis entgegen und die Kommunikation ist beendet.
Eine SOAP-Anfrage eines Clients könnte beispielsweise folgendermaßen aussehen
(ohne HTTP-Header):
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<ns1:validate
soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
1
Ein zustandsloses Protokoll ist ein Protokoll, dessen Informationen aus früheren Anforderungen verloren
gehen, wenn eine separate Anforderung gemacht wird.
15
RMI und SOAP für Java – Seminar-Arbeit von Marc Wodischek und Timo Holzherr
xmlns:ns1="urn:CardValidator">
<number xsi:type="xsd:string">1234 5678 9876 5432</number>
<valid xsi:type="xsd:string">12/08</valid>
</ns1:validate>
</soapenv:Body>
</soapenv:Envelope>
Die Antwort vom SOAP-Server (HTTP-Server) darauf könnte folgendermaßen
aussehen:
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope
sxmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<ns1:validateResponse
soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:ns1="urn:CardValidator">
<addReturn xsi:type="xsd:string">true</addReturn>
</ns1:validateResponse>
</soapenv:Body>
</soapenv:Envelope>
4.3
SOAP-Implementierungen
Natürlich muss nicht jeder Programmierer selbst server- und clientseitige Software
schreiben, welche SOAP-HTTP-Anfragen absetzen kann, auf diese Anfragen reagiert,
diese XML-Strukturen parst und nach dem Methodenaufruf wieder XML-Strukturen
generiert.
Für diese Aufgaben gibt es im Internet viele fertige Implementierungen für
unterschiedlichste Programmiersprachen und Systeme.
Für die Programmiersprache Java sind die Softwarepakete der Apache Software
Foundation zu empfehlen.
Diese beinhalten den Tomcat Webserver 1 , der HTTP-Anfragen verarbeiten kann. Der
Tomcat-Webserver erfordert eine installierte JRE 2 . Um SOAP-HTTP-Anfragen
verarbeiten zu können, benötigt der Tomcat-Server das Apache SOAP-Servlet 3 , welches
für die Anfragen später den RPC-Router bildet.
1
2
3
Erhältlich unter http://jakarta.apache.org/tomcat/index.html
Java Runtime Environment = Laufzeitumgebung für Java-Programme
Erhältlich unter http://xml.apache.org/soap/index.html
16
RMI und SOAP für Java – Seminar-Arbeit von Marc Wodischek und Timo Holzherr
4.3.1
Clientseitige SOAP-Programmierung
Clientseitig bekommt man für Java-Anwendungen ebenfalls von der Apache Software
Foundation Klassen, die SOAP-Dienste liefern. Im ZIP-Archiv des Apache SOAPServlets (s.o.) befinden sich auch alle JAR-Dateien, die man zur Entwicklung von
SOAP-Client-Anwendungen benötigt:
SOAP: soap.jar
JAVAMAIL: mail.jar
JAF: activation.jar
XERCES: xerces.jar
Hat man die vier Java-Archive in seine Codebase eingebunden, kann man ein SOAPRequest einem SOAP-Server ausführen.
Im Folgenden ist ein Code-Beispiel dargestellt, welches auf einen SOAP-Server, der
Beispiele zur Verfügung stellt, verbindet. Der RPC-Router der SOAP-Applikation ist
unter der URL „http://213.23.125.181:8080/RPC“ verfügbar. Die Methode, die
aufgerufen wird, lautet „ChristmasTree“ und läuft in der SOAP-Object-URI 1
„urn:christmas“.
Der Aufruf einer SOAP-Methode wird durch das Call-Objekt realisiert. Zunächst wird
im Beispiel ein neues Call-Objekt instanziiert. Diesem Objekt müssen daraufhin alle
Attribute, die den Methodenaufruf bestimmen, gesetzt werden. Durch den Aufruf von
setTargetURI(String) wird die SOAP-Object-URI festgelegt. Mit dem Befehl
setMethodName(String) wird festgelegt, welche SOAP-Methode der Applikation
aufgerufen werden soll.
Mit setEncodingStyleURI(String) wird festgelegt, wie Objekte serialisiert und
transferiert werden sollen. Der EncodingStyle wird in Form eines Namespaces definiert.
Je nach angegebenem Namespace wird das Objekt anders serialisiert. Bei Apache SOAP
gibt es einige vordefinierten String-Konstanten, die Namespace-Bezeichnungen
widerspiegeln. Diese sind in der Klasse org.apache.soap.Constants abgelegt. Für
Standard-Java-Objekte (String, Integer, Boolean, etc) ist der Namespace
Constants.NS_URI_SOAP_ENC geeignet. Weicht der zu übertragende Objekt-Typ von
Standard-Datentypen ab, muss je nach Typ der passende Namespace gewählt werden.
1
Ein SOAP-Object-URI ermöglicht es, mehrere Applikationen auf einem RPC-Router zu installieren. Jede
Applikation hat ein eigenes Object-URI, unter der sie erreichbar ist. Jedes Object-URI (also jede Applikation)
kann viele Methoden besitzen.
17
RMI und SOAP für Java – Seminar-Arbeit von Marc Wodischek und Timo Holzherr
Erwartet die aufzurufende Methode Parameter, kann man diese durch
Call.setParams(Vector) setzen. Der Vector beinhaltet eine Liste von ParameterObjekten. Ein Objekt vom Typ Parameter repräsentiert je einen Parameter der
aufzurufenden Methode und wird durch den Konstruktor new Parameter(String name,
Class type, Object value, String encodingStyleURI) erzeugt. Der Parameter name des
Konstruktors steht für den Namen des Parameters der entfernten Methode, der definiert
werden soll. Der Parameter type gibt an, von welchem Typ der Parameter ist (Bspw.
String.class). Der Parameter value steht für den zu übergebenden Wert. Der Parameter
encodingStyleURI gibt an, wie der Parameter serialisiert werden soll (Die Werte, die
angegeben werden können, entsprechen denen der Methode setEncodingStyleURI (s.o.))
Dieser Parameter muss jedoch nur angegeben werden, wenn der Wert des Parameters
von der Default-Encodingstyle-URI, welche mit Call.setEncodingStyleURI zuvor gesetzt
wurde, abweicht. Ist dies nicht der Fall, kann stattdessen null angegeben werden.
Sind diese Attribute dem Call-Objekt zugewiesen, kann durch den Aufruf der Methode
Call.invoke(java.net.URL, String) der entfernte Methodenaufruf durchgeführt werden.
Als Parameter erwartet die Methode zum einen die URL des RPC-Routers (hier
„http://213.23.125.181:8080/RPC“). Zum anderen erwartet die Methode den 2.
Parameter SOAPActionURI, welche im Normalfall als Leerstring („“) gesetzt werden
kann.
Die Methode invoke kann bei einem Fehler bei der Kommunikation mit dem SOAPServer eine SOAPException werfen. Diese muss abgefangen werden.
Bei erfolgreichem Ausführen der Methode invoke liefert sie ein Response-Objekt zurück,
welches die Antwort auf die SOAP-Anfrage repräsentiert.
Nicht alle Probleme, die bei der Datenübertragung auftreten können, werfen eine
SOAPException. Wird versucht, eine Methode aufzurufen, die nicht existiert, führt dies
nicht zu einer Ausnahme. Die Methode generatedFault() gibt Antwort auf die Frage, ob
ein interner Fehler auftrat.
Ist dies nicht der Fall, so bekommt man durch den Aufruf der Methode
Response.getReturnValue() das Ergebnis des Methodenaufrufs in Form eines ParameterObjektes. An den eigentlichen Wert kommt man durch den Aufruf von
Response.getReturnValue().getValue(), was eine Referenz vom Typ Object zurückliefert.
18
RMI und SOAP für Java – Seminar-Arbeit von Marc Wodischek und Timo Holzherr
Call call = new Call();
call.setTargetObjectURI( "urn:christmas" );
call.setMethodName( "ChristmasTree" );
call.setEncodingStyleURI( Constants.NS_URI_SOAP_ENC );
Vector p = new Vector();
p.addElement( new Parameter("h", double.class, new Double(200), null ) );
p.addElement( new Parameter("r", double.class, new Double(100), null ) );
p.addElement( new Parameter("l", double.class, new Double(10), null ) );
call.setParams( p );
Response resp = null;
try
{
URL url = null;
try {
url = new URL( "http://213.23.125.181:8080/RPC"; );
} catch ( MalformedURLException e ) {}
resp = call.invoke( url, "" );
}
catch( SOAPException e )
{
System.err.println( "SOAPException (" + e.getFaultCode() + "): " +
e.getMessage() );
System.exit(0);
}
if ( !resp.generatedFault() )
{
Parameter ret = resp.getReturnValue();
Object value = ret.getValue();
System.out.println( value );
}
else
{
Fault fault = resp.getFault();
System.err.println( "Fehler bei der Ausführung: " );
System.out.println( " Fault-Code
= " + fault.getFaultCode() );
System.out.println( " Fault-String = " + fault.getFaultString() );
}
4.3.2
Serverseitige SOAP-Programmierung
Hat man den Tomcat-Webserver und das SOAP-Servlet installiert und konfiguriert, kann
man über die Web-Oberfläche von SOAP (siehe Abbildung 1) neue SOAPApplikationen installieren (Deploy).
19
RMI und SOAP für Java – Seminar-Arbeit von Marc Wodischek und Timo Holzherr
Abbildung 3: SOAP-Administrationsoberfläche
Um die Methoden, die von SOAP-Requests ausgeführt werden sollen, zu
implementieren, erstellt man eine neue Klasse, die jede dieser Methoden implementiert.
Beispiel:
public class SoapServerClass{
public String getHelloWorldString(){
return(“Hello World”);
}
}
Diese Klasse wird dann beim Installieren einer neuen SOAP-Applikation als Java
Provider Class eingetragen.
Will man statt den Java Standard-Datentypen eigene Datentypen über die SOAPSchnittstelle übertragen, muss man jeden dieser eigenen Datentypen auch beim
Eintragen als SOAP-Applikation in die Type-Mappings-Tabelle eintragen. Es muss
definiert werden, wie Objekte serialisiert und deserialisiert werden können. (Java to
XML Serializer, XML to Java Deserializer)
Unter http://www.soapuser.com/ ist wird sehr detailliert beschrieben, wie man serverund clientseitig SOAP-Programme entwickelt.
20
RMI und SOAP für Java – Seminar-Arbeit von Marc Wodischek und Timo Holzherr
5
Fazit
Die Architekturen RMI und SOAP bieten einfache Möglichkeiten zur Übetragung von
Objekten. Für die Programmiersprache Java sind gute Bibliotheken erhältlich, die für
den Programmierer die Übertragung der Objekte übernehmen.
Die Vorraussetzung, dass RMI und SOAP gut funktionieren ist eine gute
Netzwerkverbindung zwischen Client- und Server-Computer. Eine Lösung für
Netzwerk-Probleme zwischen Client und Server bieten RMI und SOAP jedoch auch
nicht.
SOAP hat seine Vorteile darin, dass es die Daten über standardisierte Protokolle wie
HTTP versendet. Dadurch müssen keine zusätzlichen Ports in Firewalls geöffnet
werden. Bei RMI kann zwar der TCP/IP-Port angegeben werden, über den übertragen
werden soll, trotzdem wird das RMI- Protokoll verwendet. Zudem ist eine verschlüsselte
Übertragung der Daten bei SOAP kein Problem. Da SOAP auf HTTP aufsetzen kann,
kann einfach statt HTTP HTTPS verwendet werden. Bei RMI ist eine verschlüsselte
Übertragung
der
Daten
nicht
ohne
Weiteres
möglich.
SOAP
ist
programmiersprachenunabhängig, wobei RMI hingegen den Programmierer fast
ausschließlich an Java bindet. Ein Nachteil von SOAP ist, dass die Daten durch die
XML-Representation während der Übertragung sehr groß werden und deshalb viel
Bandbreite benötigen. Beide Architekturen – SOAP und RMI – sind jedoch
Plattformunabhängig.
6
Literaturverzeichnis
[JA04] Java ist auch eine Insel
[Wik05] Wikipedia – Online – Enzyklopädie
[SO05] http://www.soapuser.com/
[W305] http://www.w3.org/TR/soap12-part
21
Herunterladen