Inhaltsverzeichnis

Werbung
1
INHALTSVERZEICHNIS
Inhaltsverzeichnis
1 Einleitung
3
2 Das Phänomen der Web Services
2.1 Definition eines Web Services . . . . . . . . . . . . . . . . . .
2.2 Web Services Architecture . . . . . . . . . . . . . . . . . . . .
5
5
6
3 Die Standards SOAP und WSDL
3.1 Simple Object Access Protokoll (SOAP) . .
3.2 Web Service Description Language (WSDL)
3.2.1 Einleitung . . . . . . . . . . . . . . .
3.2.2 Beschreibung des Sprache WSDL . .
3.2.3 SOAP Binding . . . . . . . . . . . .
3.2.4 Zusammenfassung . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
9
9
13
13
14
18
20
4 Kategorisierung von lokationsbasierten Diensten
22
4.1 Identifizierung und Klassifizierung von lokationsabhängigen
Diensten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
4.1.1 Output Services . . . . . . . . . . . . . . . . . . . . . 24
4.1.2 Input Services . . . . . . . . . . . . . . . . . . . . . . 26
4.1.3 Storage and Computation Services . . . . . . . . . . . 27
4.1.4 Device Control (Steuerungsdienste) . . . . . . . . . . . 27
4.1.5 Communication Services . . . . . . . . . . . . . . . . . 28
4.2 Konzeption einer WSDL-Taxonomie der Dienste . . . . . . . 28
4.2.1 Ausgabedienste . . . . . . . . . . . . . . . . . . . . . . 29
4.2.2 Input Services . . . . . . . . . . . . . . . . . . . . . . 38
4.2.3 Storage and Computation Services . . . . . . . . . . . 40
4.2.4 Communication Services . . . . . . . . . . . . . . . . . 42
4.3 Weitere wichtige Aspekte bezüglich lokationsbasierter Dienste 46
4.3.1 Autorisierung . . . . . . . . . . . . . . . . . . . . . . . 46
4.3.2 Authentizität . . . . . . . . . . . . . . . . . . . . . . . 47
4.3.3 Abrechnung . . . . . . . . . . . . . . . . . . . . . . . . 49
5 Beispielhafte Implementierungen für Web Services
5.1 Java Web Service Developer Pack . . . . . . . . . . .
5.1.1 Kurzbeschreibung des Pack . . . . . . . . . .
5.1.2 JAX-RPC . . . . . . . . . . . . . . . . . . . .
5.1.3 JAXM und SAAJ . . . . . . . . . . . . . . .
5.2 Beispielimplementierungen für Druckdienste . . . . .
5.2.1 PrintManagement – Bottom-Up-Ansatz . . .
5.2.2 PrintManagement - Top Down Ansatz . . . .
5.2.3 JAXM-basierter PrintService . . . . . . . . .
6 Abschließende Bemerkungen
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
51
51
51
52
58
60
61
66
67
73
2
INHALTSVERZEICHNIS
A Taxonomie
79
B selbstdefinierte WSDL für den Druckdienst
82
C PrintService – HTTP-Servlet
85
C.1 Client-Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
C.2 Service-Code . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
Einleitung
1
3
Einleitung
Durch die immer stärker werdende Vernetzung von Rechnern und durch die
weitere Verbreitung von unterschiedlichen Devices (wie Handy, PDA, usw.),
die auf verschiedenen Plattformen arbeiten, werden verteilte Anwendungen
bzw. Systeme immer wichtiger. Unter verteilten Anwendungen sind lose über
das Internet gekoppelte Softwarekomponenten zu verstehen, die idealerweise
zur Laufzeit zueinander finden und damit den Anforderungen an Flexibilität
und Dynamik entsprechen. Um dies zu realisieren, wurde das Konzept der
Web Services entwickelt, die sich von normalen Web-Anwendungen dadurch
unterscheiden, dass sie nicht auf eine Benutzung durch Menschen, sondern
”
auf eine automatisierte Benutzung ausgerichtet sind“ [Kre02]. Sie verwenden
XML als plattformunabhängige Sprache zur Beschreibung der Schnittstellen
und der Daten, die zwischen den einzelnen Anwendungen übertragen werden. Zur Datenübertragung wird das Internet genutzt, da es heutzutage eine
weite Verbreitung erreicht hat und nahezu allgegenwärtig ist.
Damit die Anwendungen in der Tat Just in Time“ und automatisch zuein”
ander finden, ist eine Standardisierung der Beschreibung von Web Services
notwendig. Schließlich sind Maschinen noch nicht in der Lage, die Semantik
von verschiedenen Worten zu verstehen, sofern sie nicht eindeutig festgelegt
ist. Zur Beschreibung von Web Services und der Nachrichten, die zwischen
den Anwendungen ausgetauscht werden, wird ein Standard names WSDL
(Web Service Description Language) von der Standardisierungsorganisation W3C entwickelt, der von mehreren großen Unternehmen, unter anderem
IBM, Ariba und Microsoft, unterstützt wird und damit gute Aussichten auf
verbreitete Verwendung besitzt. Jene Beschreibungssprache wird auch innerhalb der vorliegenden Arbeit benutzt, um Dienste zu beschreiben. Aber
Dienste müssen nicht nur beschrieben werden, sie müssen auch publik gemacht werden, andernfalls wäre ein automatisches Service Discovery“ nicht
”
möglich. Aufgrund dessen werden die Web Services in öffentlichen Verzeichnissen publiziert, deren Einträge ebenfalls standardisiert sein sollten, damit
ein Software-Agent in diesen nach geeigneten Diensten für seinen Client suchen kann. Wichtig ist dabei nicht nur, dass die Dienste in den richtigen
Kategorien eingeordnet sind, um gefunden zu werden, sondern auch, dass
alle benötigten Auswahlkriterien, wie beispielsweise Kosten und Standort
des Dienstes, angegeben sind. Letzteres ist vor allem für lokationsbasierte
Dienste wichtig, für die im Rahmen dieser Arbeit eine Taxonomie erstellt
wird.
In der vorliegenden Arbeit wird in Kapitel 2 zunächst definiert, was unter
einem Web Service zu verstehen ist. Ferner werden die einzelnen Komponenten einer Web Service Struktur beschrieben. Anschließend werden in Kapitel
3 das Nachrichtenübertragungsformat SOAP und die Dienstbeschreibungs-
4
Einleitung
sprache WSDL beschrieben. Im folgenden Kapitel werden zunächst lokationsbasierte Dienste identifiziert und eine Taxonomie für diese entwickelt. Jene kategorisierten Dienste werden anschließend mit WSDL-Fragmenten beschrieben, wobei der Aspekt Modularisierung berücksichtigt wird. Darüber
hinaus werden noch weitere für Web Services wichtige Aspekte diskutiert:
Autorisierung, Authentisierung und Abrechnung. Im zweiten Teil der Arbeit (Kapitel 5) wird ein Druckdienst exemplarisch implementiert. Benutzt
wird dazu das Java Web Services Developer Pack von Sun Microsystems,
insbesondere die APIs JAX-RPC und JAXM. Untersucht wird auch, inwieweit die in Kapitel 4 erstellten WSDL-Fragmente bei der Implementierung
verwertet werden können.
Das Phänomen der Web Services
2
2.1
5
Das Phänomen der Web Services
Definition eines Web Services
Frank Coyle bezeichnet in seinem Buch XML, Web Services, and the Da”
ta Revolution“ die Web Services als Technologie, Prozess und Phänomen
zugleich [COY02]. Aus technologischer Sicht handelt es sich bei Web Services seiner Meinung nach um eine Menge von Protokollen, die auf die durch
SOAP, XML und HTTP ermöglichte globale Kopplung von Anwendungen
aufbauen. Als Prozess eröffnen Web Services die Möglichkeit, Dienste über
das Internet zu entdecken und zu verbinden bzw. zu nutzen. Web Services
sind aber auch ein Phänomen, denn die wichtigsten Industrien entwickeln
Systeme, die diese Technik unterstützen, da sie etliche Vorteile in sich birgt
und sich deswegen weit verbreiten wird. Der Vorteil liegt in der Flexibilität
und Effizienz des Konzepts, da es die Verbindung lose gekoppelter Systeme
ermöglicht, ohne auf eine spezielle Programmiersprache, Komponentenmodell oder Plattform angewiesen zu sein. Trotz dieser guten Aussichten ist
Coyle der Meinung, dass die Technologie Web Service noch in den Kinder”
schuhen“ steckt und die bisherigen Unterstützer als Early Adopters“ be”
zeichnet werden müssen, und die Investition nicht ganz risikofrei ist, schließlich werden bis zur Reife der Technologie noch einige Jahre vergehen. Des
Weiteren können Leute von der losen Kopplung von Services spätestens zur
Laufzeit des Programmes erst profitieren, wenn es genügend Unternehmen
bzw. Personen gibt, die Web Services über das Internet anbieten und damit eine genügend große Auswahl an solchen Diensten vorhanden ist. Dabei
kann ein Web Service alles mögliche anbieten – von einer einfachen Auskunft
bis hin zu einer komplizierten Kreditkartentransaktion. Aber was sind Web
Services eigentlich? Von der Standardisierungsorganisation W3C werden sie
wie folgt definiert:
Definition 1 (Web Service) : A Web Service is a software system iden”
tified by a URI, whose public interfaces and bindings are defined and described using XML. Its definition can be discovered by other software systems.
These systems may then interact with the Web service in a manner prescribed by its definition, using XML based messages conveyed by internet
protocols.“ [CHA02]
Diese Definition der W3C setzt nur die Nutzung von XML voraus, nicht
die Nutzung von Techniken wie SOAP oder WSDL, die nachfolgend beschrieben werden; sie ist damit wesentlich allgemeiner und umfassender, als
die Beschreibung eines Web Services von F. Coyle und wird aus diesem
Grund in dieser Arbeit als die Definition eines Web Services gewählt. Ein
Web Service unterscheidet sich nach der obigen Definition von einer normalen Web-Anwendung dadurch, dass der Austausch von Informationen bzw.
Nachrichten auf XML basiert und der Dienst selbst mit Hilfe von XML be-
6
Web Services Architecture
schrieben wird. Die Benutzung von XML als Sprache eröffnet die Möglichkeit, dass solche Web Services auch von Maschinen entdeckt und benutzt
werden können, ganz ohne das Hinzutun eines Menschen. Im folgenden Abschnitt sollen nun die einzelnen Komponenten eines Web Services genauer
beschrieben werden.
2.2
Web Services Architecture
Bezüglich der Architektur eines Web Services wird in eine Basis Architek”
tur“ und eine Erweiterte Architektur“ unterschieden [CHA02]. In der Ba”
”
sis Architektur“ wird ein Web Service als der Austausch von Nachrichten
zwischen Software Agents“ beschrieben, die eine der folgenden drei Rollen
”
annehmen können: Service Provider“ (Dienstanbieter), Service Requestor“
”
”
(Dienstnachfrager) oder Service Discovery Agency“ (siehe Abbildung 1).
”
Discovery
Agency
Publish
Find
Service
Requestor
Refer
Interact
Service
Provider
Refer
Use
Servicedescription
Abbildung 1: Basis Architektur. Quelle: [CHA02]
Der Service Provider“ stellt einen Dienst, den er implementiert hat, über
”
eine URI im Netz zur Verfügung und erstellt eine XML Beschreibung seines
Web Services, die angibt, wo der Dienst zu finden ist, welche Operationen er
unterstützt, wie das Format der Ein- und Ausgabedaten beschaffen sein muss
und welches Protokoll zur Übertragung benutzt werden soll [Kre02]. Diese
Beschreibung kann dann im Internet über einen beliebigen Host (dies kann
der Service Provider“ selbst sein) veröffentlicht und damit zur Verfügung
”
Web Services Architecture
7
gestellt werden. Der Dienst kann anschließend in einem Verzeichnis, einer
Service Discovery Agency“, nach unterschiedlichen Kriterien bekannt ge”
macht werden. Im dem Verzeichniseintrag kann der Service auf die XMLBeschreibung seines Services verweisen; ist der Dienst in keinem Verzeichnis
eingetragen, so kann dies der Dienstanbieter auch selbst tun, ebenso ist es
möglich, im Falle fester Vereinbarungen bzw. Geschäftsverbindungen, die
Datei mit der Beschreibung direkt an den Client zu senden.
Der Service Requestor“, der den Dienst erfragt, kann entweder in dem Ver”
zeichnis oder im Internet nach einem für ihn geeigneten Dienst suchen. Hat
ein Dienstnachfrager einen entsprechenden Dienst, der seine Auswahlkriterien erfüllt, ausgewählt, kann er diesen Dienst aufrufen. Dazu benutzt er
die Dienstbeschreibung, die er über das Verzeichnis oder den Provider des
Service-Anbieters erhalten hat. Ein Software-Agent kann dabei gleichzeitig in einer oder mehreren Rollen agieren, dass heißt beispielsweise, dass ein
Service Provider“ ebenfalls ein Service Requestor“ sein kann, falls er einen
”
”
Teil des angebotenen Dienstes nicht selbst ausführen kann.
In der Erweiterten Architektur“ werden neben der eben beschriebenen
”
Basisfunktionalität noch zusätzliche Funktionen bzw. Features angeboten,
die die vorhandene Technologie und Komponenten erweitern. Hier sind einige Beispiele für zusätzliche Funktionalität:
• Asynchronous Messaging
• Unterstützung von (langen) Transaktionen
• Zuverlässigkeit der Nachrichten (Schutz vor Verlust von Nachrichten)
• Vertraulichkeit der Nachrichten (hier gibt es die Möglichkeit einer Kodierung und Dekodierung der Nachricht mittels SOAP oder der Nutzung von SSL)
• Session
• Authentifizierung und Autorisierung (Möglichkeiten ergeben sich hier
durch HTTP auth oder SOAP,...)
Für die Realisierung der oben beschriebenen Basis- und Erweiterte Funktionalität werden zurzeit mehrere Spezifikationen entwickelt. Sehr aktiv ist in
diesem Bereich die Standardisierungsorganisation W3C, die die Entwicklung
in folgenden Bereichen vorantreibt:
• UDDI (Universal Description, Discovery, and Integration) – diese Sprache unterstützt das Publizieren und Finden von Diensten in Verzeichnissen.
• SOAP (Simple Object Access Protokoll) – ein Nachrichtenformat, das
neben der Definition der Struktur einer Nachricht noch zusätzliche
Funktionalität übernehmen kann (wie beispielsweise die Autorisierung).
8
Web Services Architecture
• WSDL (Web Service Description Language) – dient zur Beschreibung
von Web Services.
Wie bereits im Kapitel zuvor erwähnt, werden jene Standards nur empfohlen, und es ist keine Pflicht diese Techniken zu verwenden, der einzige
Standard, der bei Web Services verpflichtend ist, ist XML. Im nächsten
Kapitel werden die beiden Standards SOAP und WSDL näher betrachtet,
insbesondere letztere Sprache, da sie zur Erstellung der Taxonomie von lokationsbasierten Diensten in der vorliegenden Arbeit verwendet wird.
Die Standards SOAP und WSDL
3
9
Die Standards SOAP und WSDL
Der Schwerpunkt dieser Arbeit liegt auf der Erstellung einer WSDL-Taxonomie für lokationsbasierte Dienste und damit auf dem Standard WSDL. In
Kapitel 5 werden zwei Beispiele für lokationsabhängige Web Services exemplarisch implementiert, die als Nachrichtenprotokoll SOAP und als Übertragungsprotokoll HTTP verwenden. Aus diesem Grund wird zunächst eine kurze Einführung in SOAP gegeben, bevor dann ausführlich auf WSDL
eingegangen wird. Dies soll das Verständnis der in Kapitel 5 vorgestellten
Beispielimplementierungen erleichtern, aber keine komplette Einführung in
beide Themengebiete darstellen.
3.1
Simple Object Access Protokoll (SOAP)
SOAP wurde ursprünglich von der DevelopMentor AG als plattformunabhängiges Protokoll für den Zugriff auf Dienste und Objekte zwischen Applikationen und Servern über HTTP entwickelt. SOAP verwendete dazu
ein einfaches XML-basiertes Format, um Remote Procedure Calls und ihre Eingabe- und Rückgabeparameter darzustellen. Im Jahr 1999 wurde die
Spezifikation SOAP 1.0, unterstützt von mehreren großen Firmen, veröffentlicht. Durch Beitrag weiterer Firmen (Microsoft und Lotus Corporation)
wurde schließlich die SOAP 1.1 Spezifikation als W3C Note herausgegeben.
Aktuell ist momentan die Version 1.2, die am 24.06.2003 von der Standardisierungsorganisation W3C veröffentlicht wurde [NASKSR].
SOAP ist folglich ein Nachrichtenprotokoll, das es ermöglicht, strukturierte und getypte Information zwischen Rechnern in einer dezentralisierten,
verteilten Umgebung mit Hilfe von XML auszutauschen. Da eines der Ziele
beinhaltete, dass SOAP möglichst flexibel sein soll, unterstützt der Standard mehrere unterschiedliche Übertragungsprotokolle: z.B. HTTP, FTP
und SMTP. Um SOAP-Nachrichten zu erstellen oder den Inhalt zu extrahieren und zu verwenden, müssen Objekte bzw. vernetzte Objektstrukturen serialisiert und auf XML abgebildet werden und umgekehrt. Bereit gestellt wird dazu ein modulares Paketmodell, das auch Mechanismen zur
Verschlüsselung der zu sendenden Daten anbietet.
Häufig wird in der Literatur zwischen zwei Arten von Nachrichten unterschieden: einfache SOAP Messages und SOAP Messages mit Attachments.
Im ersten Fall besteht die Nachricht nur aus dem SOAP Envelope, der im
rechten Teil von Abbildung 2 abgebildet ist. Dessen SOAP Body enthält
entweder die Daten eines RPC-Aufrufs oder ein Dokument in XML-Format.
Im zweiten Fall werden an die Nachricht eine oder mehrere Dateien in beliebigen Format angehangen. Jede SOAP Message kann folglich aus bis zu
vier Komponenten bestehen:
1. einem Umschlag (SOAP Envelope): Der Umschlag ist das Wurzelelement und dient als Behälter für die gesamte Nachricht. Er besitzt zwei
10
Simple Object Access Protokoll (SOAP)
direkte Kindelemente: den Header (Kopf) und den Body (Datenbereich).
2. einem optionalen SOAP Header (Nachrichtenkopf): Der SOAP Header kann genutzt werden, um Informationen oder Anweisungen, abseits
des eigentlichen Funktionsaufrufs, an den Empfänger oder eine dritte
Person zu übermitteln. Soll eine Nachricht über mehrere Knoten (Stationen) im Netz laufen, so kann dies im Header eingetragen werden.
Jede Zwischenstation kann entweder bestimmte Funktionen ausführen
oder einfach nur die Nachricht weiterleiten. Bei den Zusatzfunktionen kann es sich zum Beispiel um eine Authentisierung oder um das
Einleiten einer Transaktion handeln.
3. einem SOAP Body (Körper): Der Body einer Nachricht enthält die Daten, die für den Empfänger der Nachricht bestimmt sind. Der genaue
Inhalt des Körpers hängt dabei von der Art der SOAP-Nachricht ab.
Im Falle eines entfernten Funktionsaufrufs (Remote Procedure Call)
wird zwischen drei verschiedenen Arten von Nachrichten unterschieden: Anfrage (Request), Antwort (Response) oder Fehlerbeschreibung
(Fault). Bei einer Anfrage enthält der SOAP Body den Namen der
aufzurufenden Funktion inklusive aller für die Ausführung des Aufrufs
benötigten Daten bzw. Parameter. Bei erfolgreicher Ausführung der
Funktion wird eine SOAP-Nachricht zurückgeschickt, die im Body das
Ergebnis des Funktionsaufrufs an den Aufrufenden zurückliefert. Obwohl das Protokoll ursprünglich für den Funktionsaufruf gedacht war,
ist es zusätzlich möglich, One-Way Messages zu schicken. Der Body
enthält dann beliebige Daten im XML-Format, die der Empfänger der
Nachricht über einen Parser einlesen und verwerten kann. Bei den Daten kann es sich auch um ganze Dateien (im XML-Format) handeln.
Ein solcher Ausstauch von Daten wird als dokumentenbasiert“ be”
zeichnet. Im Falle eines Fehlers - falscher Aufbau der SOAP-Nachricht
oder Fehler bei der Bearbeitung - werden im Body der Nachricht detaillierte Fehlerinformationen zurückgeliefert.
4. einem optionalen AttachmentPart (Anhang): In dem Körper der SOAPNachricht können nur Daten im XML-Format transportiert werden.
Sollen Daten in einem anderen Format oder ganze Dateien übertragen werden, kann der AttachmentPart der SOAP-Nachricht verwendet
werden. Eine SOAP Message mit Attachments wird auch SOAP mes”
sage package“ genannt und benutzt die Technik MIME (Multipurpose
Internet Mail Extensions), einen Standard, der das Format von Internet Mails erweitert, indem mehrere Nachrichten-Körper-Teile (Body
Parts), die jeweils ein unterschiedliches Format besitzen können, zugelassen werden.
11
Simple Object Access Protokoll (SOAP)
In Abbildung 2 ist die Struktur einer SOAP-Nachricht dargestellt, wobei
der rechte Teil eine einfache SOAP-Nachricht repräsentiert und die gesamte
Grafik eine SOAP Message mit Attachments.
SOAP Message
MIME Header
SOAP Envelope
MIME Boundary Root Body Part
SOAP Envelope
(text/xml)
SOAP Header
Header Entry
Header Entry
MIME Boundary Body Part
Attachment
MIME Boundary Body Part
...
MIME Boundary Body Part
Body Entry
...
Attachment
SOAP Body
Body Entry
Attachment
Abbildung 2: SOAP Message. Quelle:[ORMA02] und [NASKSR]
An dieser Stelle wird anhand von zwei Beispielen gezeigt, wie die übertragenen Nachrichten aussehen. Zunächst folgt eine einfache SOAP Message
ohne Attachment, die mittels des Übertragungsprotokolls HTTP übermittelt wurde.
POST /StockQuote HTTP/1.1
Host: www.stockquoteserver.com
Content-Type: text/xml; charset:"utf-8"
Content-Length: nnn
SOAPAction: "Some-URI"
<SOAP-ENV: Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
SOAP-ENV:encodingstyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Header />
<SOAP-ENV:Body>
<m:GetLastTradePrice xmlns:m="some-URI">
<symbol>DEF</symbol>
</m:GetLastTradePrice>
</SOAP-ENV:Body>
</SOAP-Envelope>
Dieses Beispiel ist aus dem Java Web Services Developer Pack [ORMA02]
entnommen, das in Kapitel 5 genauer beschrieben ist. Die Nachricht ruft auf
dem Host www.stockquoteserver.com die Funktion GetLastTradePrice auf,
um die letzte Börsennotation der Aktie DEF herauszufinden. Nachfolgend
ist ein Beispiel für eine SOAP Message mit Attachment dargestellt:
12
Simple Object Access Protokoll (SOAP)
MIME-Version: 1.0
Content-Type: Multipart/Related;
boundary=MIME_boundary; type=text/xml;
start="anyURI"
Content-Type-Description:
This is the optional message description.
--MIME_boundary
Content-Type: text/xml; charset=UTF-8
Content-Transfer-Encoding: 8 bit
Content-ID: <"anyURI">
<?xml version="1.0"?>
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header>
...
</SOAP-ENV:Header>
<SOAP-ENV:Body>
...
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
--MIME_boundary
Content-Type: image/tiff
Content-Transfer-Encoding:binary
Content-ID: <"anyURi">
...binary TIFFimage...
--MIME_boundary--
Dem Beispiel kann entnommen werden, dass die Nachricht aus einem MIME Header und mehreren Body Parts mit jeweils eigenem Header und Body
besteht, wobei die Body Parts durch ein sogenanntes MIME boundary voneinander getrennt werden. Über das Attribut Content-Type kann das Format
für den jeweiligen body part“ definiert werden und mittels des Attributs
”
Content-Transfer-Encoding das Kodierungsformat. Der Content-Type des
Headers ist auf den Wert Multipart/Related gesetzt, der angibt, dass die
Nachricht aus mehreren zusammenhängenden Body Parts besteht. Einer der
Body Parts ist der sogenannte Root Body Part“ (im Default-Fall ist dies der
erste Body Part), er enthält den SOAP Envelope. In der Regel verweist der
Root Body Part durch Referenzen im Header oder Body des SOAP Envelopes auf die anderen Body Parts.
An dieser Stelle sollen kurz die wesentlichen Eigenschaften von SOAP zusammengefasst werden:
• transportiert in XML-Notation kodierte Funktionsaufrufe und Parameter von einer Quelle zum Ziel
• ermöglicht Austausch von Information zwischen Applikationen
Web Service Description Language (WSDL)
13
• basiert auf den bereits etablierten Standards HTTP und XML
• robuster und flexibler als die get- und post-Funktionen von HTTP
• SOAP ist plattformunabhängig
• SOAP ist sprachenunabhängig
• Einfachheit
• Erweiterbarkeit
• SOAP gilt als Standard des W3C
• mit Hilfe von SOAP können RPC-Aufrufe über Firewallgrenzen hinweg
einfach realisiert werden.
3.2
3.2.1
Web Service Description Language (WSDL)
Einleitung
Das Ziel bei der Erstellung eines Web Services ist die Anforderung, den Service so zu definieren, dass er nicht nur von Menschen, sondern auch von
Applikationen benutzt werden kann. Aber wer sagt einer Maschine, was ein
spezieller Service kann und wo er zu finden ist? Aus diesem Grund wurde
von den Unternehmen Ariba, IBM und Mircosoft die Web Service Description Language (WSDL) entwickelt, deren erste Version im September 2000
veröffentlicht wurde. Die nächste Version WSDL 1.1 [CHR01] wurde im März
2001 bei der Standardisierungsorganisation W3C eingereicht, wo WSDL zur
Zeit noch weiterentwickelt wird. Aktuell ist zum Zeitpunkt der Erstellung
dieser Arbeit die Version WSDL 1.2 [CHI03], die als Working Draft“ am
”
11.06.2003 herausgegeben wurde und in diesem Kapitel beschrieben werden soll. Eine solche auch von Maschinen verständliche bzw. verarbeitbare
Sprache hat mehrere Vorteile [BOO03]:
• Sie ist formaler und daher genauer als eine natürliche Sprache (sie
besitzt eine eindeutige Semantik).
• Mit ihrer Hilfe können Softwaretools automatisch stub“- oder skele”
”
ton“-Code (Code-Gerüste oder auch einzelne Klassen ) generieren, dies
führt zu einer erleichterten Implementierung für Dienstanbieter und nachfrager.
• Sie unterstützt die dynamische Entdeckung (Selektion) und Nutzung
von Diensten.
• Sie erleichtert Schiedsgerichtsverfahren, da die Sprache eindeutig ist
(ihre Semantik ist eindeutig festgelegt), wodurch die Geschäftsbedingungen zwischen Dienstanbieter und -nutzer ebenfalls eindeutig geregelt sind.
14
Web Service Description Language (WSDL)
Die Anforderung an die Sprache ist wie Kuschke und Wölfel in ihrem Buch
schreiben sehr hoch: Ziel einer WSDL-Beschreibung ist die Schaffung ei”
nes maschinen- oder besser von Applikationen lesbaren Zugangs zu angebotenen Diensten. Es soll also im Sinne einer Applikation-zu-ApplikationKopplung (A2A) eine weitgehend automatische Integration von verschiedenen angebotenen Diensten zu neuen Anwendungen möglich werden. Anders
als bei hergebrachten Integrationen ist hierbei das Fernziel, dass Applikationen automatisch und auf der Basis solcher Beschreibungen zur Laufzeit
eines Programms die gerade benötigten Dienstleistungen dynamisch einbinden. WSDL ist also bei Web Services das Mittel, dass eine automatische Anwendungsintegration ’Just in Time’ erlaubt.“[KUWÖ]. Im Folgenden wird
nun die Sprache beschrieben, die diesen Anforderungen soll.
3.2.2
Beschreibung des Sprache WSDL
Der Standard WSDL wird von der W3C wie folgt beschrieben:
Definition 2 (WSDL) Die Web Services Description Language (WDSL)
stellt ein Modell und ein XML-Format bereit, um Web Services zu beschreiben. WSDL ermöglicht die Separation der Beschreibung der abstrakten Funktionalität, die von einem Service angeboten wird, von den konkreten Details
der Servicebeschreibung (beispielsweise das wie“ und wo“ die Funktiona”
”
lität gewährt wird). [CHI03].
Einfacher gesagt, besteht ein WSDL-Dokument aus einer Reihe von Definitionen im XML-Format, die beschreiben, was ein Service tun kann, wo er
sich befindet und wie er aufgerufen werden kann. Da ein WSDL-Dokument
aus Definitionen im XML-Format besteht, erhielt das Wurzelelement treffenderweise den Namen <definitions>. Das Wurzeltag definitions“ dient als
”
Container für die WSDL-Komponenten (<message>, <interface>, <binding>
und <service>) und Typsystemkomponenten (Typdefinitionen, Elementdeklarationen).
<definitions targetnamespace="xs:anyURI">
<documentation />?
[ <import /> | <include />]*
<types />?
[ <message /> | <interface /> | <binding /> | <service /> ]*
</definitions>
Anmerkung: Die Notation der in diesem Kapitel dargestellten Beispiele entspricht der EBNF (Extended Backus-Naur Form), die von XML 1.0 [BRA00]
benutzt und beschrieben ist.
Das oben angegebene WSDL-Fragment ist der WSDL1.2-Beschreibung entnommen [CHI03] und liest sich wie folgt: Jedes <definitions>-Element
besitzt ein Attribut targetnamespace, dessen URI auf ein maschinell oder
Web Service Description Language (WSDL)
15
durch Menschen lesbares Dokument verweist, das entweder direkt oder indirekt die Semantik des WSDL-Infosets definiert (siehe Abbildung 3). Des
Weiteren besitzt die Definitionskomponente mehrere Kindelemente, wobei
die Elemente <documentation> und <types> optional eingefügt werden
können. Die anderen beiden untergeordneten Elementgruppen können alle innerhalb ihrer Gruppe in einer WSDL-Datei gar nicht oder mehrfach in
beliebiger Reihenfolge auftauchen. Im Folgenden werden die einzelnen Kindkomponenten, die im Rahmen dieser Arbeit wichtig sind, näher betrachtet.
Sem/
BLA
WSD
Client
Applikation
Web
Service
Abbildung 3: Semantik und WSDL. Quelle: [BOO03]
include, import Die WSDL Spezifikation stellt zwei Mechanismen zur
Modularisierung von Servicebeschreibungen zur Verfügung; zum einen das
<include>- und zum anderen das <import>-Element. Ersteres dient der Separation verschiedener Komponenten einer Servicedefinition in unabhängige WSDL-Dokumente, die beliebig zusammengesetzt werden können. Dabei müssen die Komponenten den gleichen Zielnamensraum (target namespace) besitzen wie das Dokument, in das sie inkludiert werden. Dieser Mechanismus erlaubt einen modularen Aufbau von WSDL-Dokumenten sowie
das Anlegen von Bibliotheken für häufig verwendete Beschreibungsregeln.
Das import-Element hingegen dient der Separation von Komponenten einer WSDL-Beschreibung in unabhängige Beschreibungen, wobei diese unterschiedliche Zielnamensräume (target namespaces) besitzen dürfen. [CHI03]
Der Zielnamensraum entspricht der Webadresse, unter der die Beschreibung,
das Schema oder was auch immer später zu finden ist.
16
Web Service Description Language (WSDL)
<include location="xs:anyURI">
<documentation />?
</include>
<import namespace="xs:anyURI" location="xs:anyURI"?>
<documentation />?
</import>
Die beiden oben genannten Mechanismen können genutzt werden, um andere WSDL-Dokumente oder XML-Schemata zu inkludieren. Auf diese Weise
ist es ebenfalls möglich, die verschiedenen Elemente einer einzelnen ServiceDefinition in unabhängigen Dokumenten zu speichern. So können beispielsweise die abstrakten Elemente einer Service-Definition von den konkreten getrennt werden oder nach Grad der Abstraktheit definiert werden. Die Trennung in unabhängige Dokumente erhört die Übersichtlichkeit und Klarheit
der Service-Definitionen und maximiert die Wiederverwendbarkeit der einzelnen Teile einer Service Definition (vgl. [CHR01]). Das <import>-Element
wird in Kapitel 4 bei der Erstellung einer WSDL-Taxonomie von lokationsbasierten Diensten mehrfach benutzt; dort befinden sich dementsprechend
mehrere Beispiele für die Nutzung dieses Mechanismus.
types Wie hängt WSDL mit dem XML-Schema zusammen? WSDL unterstützt die Benutzung des XML-Schemas zur Definition eigener strukturierter (einfache und komplexe) Datentypen. Schließlich ist die Struktur der
Sprache WSDL selbst in XML-Schema definiert worden. WSDL verwendet
genauso wie das XML-Schema Namensräume, um Konflikte bei gleicher Namensgebung zu vermeiden. Die Typ- bzw. Elementdefinitionen können zwischen den beiden Tags <types> und </types> direkt in der WSDL-Datei
definiert oder importiert werden.
message Die Komponente <message> beschreibt in abstraktem Format
die Nachrichten, die von einem Dienst empfangen oder gesendet werden. Sie
besteht aus mehreren logischen <part>-Elementen (den Teilen einer Nachricht), deren Format mit Referenz auf eine Typ- oder Elementdeklaration
festgelegt wird. Im Falle einer SOAP-RPC-Nachricht entsprechen <part>Elemente den Ein- und Ausgabeparametern der Operation. Zur Elementbzw. Typdeklaration wird von der Standardisierungsorganisation W3C, wie
bereits erwähnt, das XML-Schema empfohlen. Des Weiteren ist anzumerken,
dass die Nachrichten einen eindeutigen Namen NCName besitzen müssen, damit sie später bei der konkreten Bindung an ein Netzwerkprotokoll und bei
der Gruppierung von Nachrichten innerhalb von Operationen referenziert
werden können.
<message name="xs:NCName">
<documentation />?
<part name="xs:NCName element="xs:QName"? type="xs:QName"?/>*
</message>
Web Service Description Language (WSDL)
17
interface Analog einer traditionellen Programmierschnittstelle besteht das
Element <interface> aus einer Gruppe von Operationen. Jede der Operationen wiederum besteht aus null oder mehreren Eingabe-, Ausgabe- und
Fehlernachrichten, die über ihren eindeutigen <message>-Namen an dieser
Stelle referenziert werden. Ferner kann ein <interface> über das Attribut
extends ein anderes <interface> erweitern und somit dessen Operationen
erben.
<interface name="xs:NCName"
extends="list of xs:QName"? >
<documentation />?
[<operation /> | <feature /> | <property />]*
<\interface>
wobei:
<operation name="xs:NCName"
pattern="xs:anyURI" >
<documentation />?
[<feature /> | <property /> |
<input /> | <output /> | <infault /> | <outfault />]*
</operation>
Die Referenz auf ein vorher definiertes <message>-Element mittels seines
eindeutigen Namens (QName) erfolgt in den Elementen <input> bzw. <output>
über das Attribut message wie folgt:
<input name="xs:NCName"?
message="xs:QName" />
Im Fall eines <infault> oder <outfault>-Elements kann die Referenz auch
aus einer Liste auf mehrere message-Namen bestehen.
<infault name="xs:NCName"
messages="list of xs:QName" />
Die weiteren Kindelemente <feature> und <property> werden an dieser
Stelle nicht näher betrachtet. Es wird für weitere Informationen auf Chinnici,
Gudgin, Moreau und Weerawarana [CHI03] verweisen.
binding Mit der <binding>-Komponente werden die Schnittstelle und
die darin enthaltenen Operationen an ein konkretes Nachrichtenformat und
Übertragungsprotokoll gebunden. Hierbei sind beliebig viele Anbindungen
für ein Interface möglich.
<binding name="xs:NCName"
interface="xs:QName" >
<operation>
<input name="xs:NCName"? />
<output name="xs:NCName"? />
18
Web Service Description Language (WSDL)
<infault name="xs:NCName" />
<outfault name="xs:NCName" />
</operation>
</binding>
Wie dem obigen XML-Fragment entmommen werden kann, ist in der Spezifikation WSDL 1.2 keine Bindung an ein spezielles Format vorgegeben
oder angegeben. Für einen Überblick über die einzelnen von WSDL unterstützten Anbindungsformate existiert eine eigene Spezifikation namens:
WSDL (Version 1.2) Bindings“ ([MOSC]), in der Anbindungen für SOAP
”
1.2, HTTP GET & POST und MIME definiert sind. In WSDL können für
die Anbindung an Netzwerk- und Nachrichtenprotokolle sogenannte Erweiterungselemente (benutzerdefinierte Elemente) definiert werden, die auch
als WSDL Binding Extensions“ bezeichnet werden. Sie sind sehr flexi”
ble Konstrukte, da sie dem Schreiber einer WSDL-Datei ermöglichen, die
Anbindung an das Protokoll zu ändern, ohne den Rest der Definitionen
des WSDL-Dokumentes zu berühren. Im folgenden Kapitel wird die Anbindung an SOAP näher erklärt, da diese in der Implementierung später
benutzt wird. Zunächst wird aber noch kurz auf das letzte Kindelement,
das <service>-Tag, von <defintions> eingegangen.
service Die <service>-Komponente beschreibt genau eine Schnittstelle
(<interface>), die der Service bereitstellt und enthält als Kindelemente eine Sammlung der <endpoints>, an denen der betreffende Service angeboten
wird. Dies sieht wie folgt aus:
<service name="xs:NCName"
interface="xs:QName"
targetResource="xs:anyURI"? >
<endpoint name="xs:NCName" binding="xs:QName" /> *
</service>
3.2.3
SOAP Binding
In der <binding>-Komponente wird bei Verwendung des SOAP-Protokolls
ein zusätzliches Erweiterungselement <soap:binding> definiert, das angibt,
dass dieses Protokoll verwendet wird:
<binding>
<soap:binding protocol ="uri"
style="document|rpc"?
namespaceDefault="uri"?
encodingStyleDefault="uri"? >
</soap:binding>
</binding>
Das Attribut protocol (es hieß in der WSDL 1.1 Version transport), gibt
an, welches Protokoll verwendet wird, um die SOAP Envelopes zu übertragen. In den Beispielen, die in Kapitel 5 implementiert werden, wurde als
Web Service Description Language (WSDL)
19
Übertragungsprotokoll HTTP verwendet; in der aktuellen Version SOAP 1.2
würde die URI wie folgt lauten: http://www.w3.org/2003/05/soap/bindings/
HTTP/. Andere mögliche Protokolle wären beispielsweise FTP(File Transfer Protokoll) oder SMTP (Simple Mail Transport Protokoll). Die weiteren Attribute sind optional, müssen also nicht angegeben werden. Interessant ist allerdings noch das Attribut style: Es kann einen der beiden
Werte rpc“ (Remote Procedure Call) oder document“ annehmen, der
”
”
dann für alle in dem <binding>-Element definierten Operationen gilt. Wird
das Attribut nicht angegeben, so wird der Wert document“ als Default
”
verwendet. Die Variante ’rpc’ definiert RPC-ähnliche Operationen, also
”
ein Austausch von Nachrichten, die Parameter und Rückgabewerte beinhalten. ’document’ bezeichnet einen dokumentenbasierten Nachrichtenaustausch, also Nachrichten, welche Dokumente beinhalten“ [KUWÖ]. Mit dem
encodingStyleDefault kann die Kodierungsvorschrift angegeben werden,
die für die im binding definierten Operationen verwendet werden soll. Des
Weiteren kann noch, wie der Name des letzten Attributes verrät, ein DefaultNamensraum für die Operationen spezifiziert werden.
Wie bereits beschrieben, besitzt das <binding> ein <operation>-Element
als Kindelement, in dem ebenfalls ein Erweiterungselement für die Anbindung an SOAP definiert werden kann.
<operation>
<soap:operation style="document|rpc"?
soapAction="uri"? />?
[<input> | <output>]
<soap:body namespace="uri"?
encodingStyle="uri"? />?
[</input> | <output>]
</operation>
Das Attribut style wurde bereits erklärt, allerdings gilt der Wert des Attributes hier nicht für alle Funktionen, sondern nur für die eine Operation,
innerhalb derer das Attribut festgelegt ist. Wird das Attribut nicht festgelegt, so gilt der Wert, der im <binding> definiert wurde, falls auch an
dieser Stelle kein Wert definiert wurde, so gilt automatisch document“ als
”
Defaultwert. Die URI, die im SOAP Action header eingetragen werden soll,
kann mit dem Attribut soapAction bestimmt werden. Dieses Attribut muss
bei der Übertragung von SOAP Envelopes über HTTP definiert werden,
ansonsten ist es optional, daher hat es keinen Default-Wert.
Über die Komponente <soap:body> kann spezifiziert werden, wie die Nachrichtenteile <parts> im SOAP Body Element erscheinen sollen. Folgende Eigenschaften können dabei festgelegt werden: der Namensraum (namespace),
der für den SOAP Body Block benutzt werden soll und die Kodierungsvorschrift, mit der die <part>-Elemente kodiert sind. Das Attribut encodingStyle ist eine URI, mit der die konkrete Definition der Nachricht mittels der
20
Web Service Description Language (WSDL)
abstrakten Typen der <part>-Elemente, die über das Attribut type definiert
sind, ermittelt werden kann.
Das letzte Erweiterungselement heißt <soap:address> und wird in das Tag
<endpoint> wie folgt eingesetzt:
<endpoint>
<soap:address location="uri" />
</endpoint>
Das Attribut location gibt die Adresse des Endpunktes (Ports) an, unter
der der Dienst zu erreichen ist, wobei die Adresse zu dem im <soap:binding>
spezifizierten Transportprotokoll passen muss.
3.2.4
Zusammenfassung
Dienste werden von der Sprache WSDL als eine Ansammlung von Netzwerkendpunkten oder Ports verstanden. Die abstrakte Definition der Nachrichten, die zwischen den Diensten ausgetauscht werden, sind von ihrer
konkreten Netzwerkbenutzung und ihren Datenformatbindungen getrennt
und können unabhängig voneinander geändert werden. Diese Aspekte unterstützen die Wiederverwendung von WSDL-Fragmenten oder gar ganzen
Dokumenten. Die Sprache WSDL besitzt dementsprechend folgende Vorteile:
• unabhängig von verwendeter Plattform, da XML plattformunabhängig
• unabhängig von bevorzugter Programmiersprache
• automatische Anwengungsintegration Just-In-Time“ möglich
”
• modulare Gestaltung von WSDL-Dokumenten möglich
• sehr flexibel, wodurch nachträgliche Änderungen leicht vor genommen
werden können
• erweiterbare Sprache (es können z.B. andere Anbindungen als die bereits von WSDL unterstützen definiert werden, aber auch viele andere
Elemente sind erweiterbar)
Im Folgenden werden nicht alle Services betrachtet, sondern der Schwerpunkt auf lokationsbasierte Dienste gelegt. Die Dienste müssen dabei a priori
nicht bekannt sein, sondern sollten über Ortsinformationen bei Bedarf ermittelt werden können und dem Clienten zugänglich gemacht werden. Um
dies zu ermöglichen, werden die Dienste mittels der Sprache WSDL beschrieben, wodurch mögliche Kunden alle zur Benutzung des Dienstes benötigten
Daten bei Bedarf ausmachen können. Mit Hilfe von auf dem Markt erhältlicher Software kann der Kunde sogar automatisch sub“- bzw. skeleton“”
”
Code von der WSDL-Datei generieren. Im nächsten Kapitel wird WSDL
Web Service Description Language (WSDL)
21
dahin gehend geprüft, ob die Spezifikation ausreichend ist, die nachstehende
Funktionalität zu gewährleisten:
1. ausreichende Trennung von Dienst und Implementierung mittels WSDL
2. hohe Wiederverwendbarkeit durch Modularisierung
3. Einordnung der lokationsbasierten Dienste in eine WSDL-Taxonomie
22
Kategorisierung von lokationsbasierten Diensten
4
Kategorisierung von lokationsbasierten Diensten
Ein Anbieter eines Dienstes, der einen neuen Service implementiert hat,
muss diesen publizieren, damit ihn ein Client, der diesen lokationsabhängigen Dienst benutzen möchte, finden kann. Zur Publikation werden die Web
Services in ein Dienstverzeichnis eingetragen, das über das Netz erreichbar
ist und von möglichen Nutzern gelesen werden kann. Je größer ein Dienstverzeichnis ist, desto wichtiger ist eine Strukturierung der Einträge, so dass
die Clients mit wenigen Klicks“ und geringer Wartezeit auf ihre Anfra”
ge den entsprechenden Dienst finden. Zur Strukturierung eines Verzeichnises werden die Dienste in bestimmte Kategorien eingeordnet - eine solche
Klassifizierung von Diensten in ein bestimmtes Kategoriensystem wird auch
Taxonomie genannt. Eine Taxonomie kann für einen bestimmten Zweck erstellt werden oder als Standard oder Norm mehreren Zwecken dienen. Suchdienste wie Google oder Yahoo verwenden zum Beispiel erfolgreich ihre jeweils eigenen Taxonomien zur Einordnung von Websites, um die Antwortzeit
auf eine Suchanfrage möglichst gering zu halten und gute Treffer liefern zu
können. Ein Beispiel für eine standardisierte internationale Klassifikation ist
die United Nations Standard Product and Services Classification (UNSPSC)
Taxonomie, die das erste Industrie- und Dienstkategorisierungssystem ist,
das für den Electronic Business“ bzw. den globalen Markt definiert wurde
”
[GRA01]. Trotz seines großen Umfanges besteht dieses Kategorisierungssystem nur aus vier Hierarchieebenen und entspricht damit der Anforderung,
dass ein Nutzer schnell zu dem gewünschten Eintrag navigieren kann.
Im Zusammenhang mit den bei Web Services benutzten Standards WSDL
und SOAP wird auch der Standard UDDI empfohlen. Die Technologie Universal Description, Discovery, and Integration (UDDI) definiert Schnittstellen und Mechanismen für Verzeichnisse zur Publikation und Speicherung
von Diensten auf Basis von Nachrichten im XML-Format. UDDI definiert
dabei sowohl die Struktur für ein universelles Verzeichnis, in dem die Dienste
abgelegt werden können, als auch Funktionen, mit deren Hilfe die Verzeichnisdaten durchsucht und modifiziert werden können [NASKSR]. Zur Kategorisierung werden bei dieser Technik die Taxonomien NAICS (North American Industry Classification System), das eben erwähnte UNSPSC, die ISONorm 3166 und das Kategorisierungssystem Operator Specific unterstüzt
[NASKSR]. Der NAICS-Index ist ein aus sechs Ziffern bestehender Klassifizierungscode, der nach Industrien und Industriezweigen klassifiziert. Er
wurde zur statistischen Erfassung und Vergleichbarkeit von wirtschaftlichen
Daten zwischen Mexiko, Kanada und den USA entwickelt (www.naics.com).
Die ISO-Norm 3166 ist ein Klassifizierungssystem, das auf geographischen
Unterteilungen beruht. Das letzte Kategorisierungssystem ist ein offenes System, das nicht vordefiniert ist und in das dementsprechend alle Kategorien
Identifizierung und Klassifizierung von lokationsabhängigen
Diensten
23
eingetragen werden können, die jemand in der Taxonomie definieren möchte
[NASKSR].
Diese Taxonomien können zur Kategorisierung von lokationsbasierten Diensten allerdings nicht benutzt werden, da die eben genannten Einteilungen für
andere Zwecke generiert wurden. Eine geeignete Kategorisierung für lokationsbasierte Dienste existierte bis UDDI 2.1 noch nicht, ab der Version 3.1
gibt es das Element keyedReferenceGroup, das als Ansatz dienen kann, um
Ortsinformationen in einem UDDI Verzeichnis zu berücksichtigen [BEL02].
Im Rahmen dieser Arbeit soll eine eigene Taxonomie definiert werden, die
im folgenden Kapitel nachgeschlagen werden kann.
4.1
Identifizierung und Klassifizierung von lokationsabhängigen Diensten
In diesem Unterkapitel werden zunächst die ermittelten lokationsbasierten
Dienste in einer selbst definierten Taxonomie angeordnet. Im folgenden Kapitel können dann die WSDL-Beschreibungen der Dienste bzw. Dienstkategorien nachgelesen werden. Diese Taxonomie erhebt keinen Anspruch auf
Vollständigkeit, da sie - speziell im unteren Bereich der Klassifizierung - die
Dienste einer vorhandenen technischen Infrastruktur berücksichtigt; außerdem ist davon auszugehen, dass die zukünftige Entwicklung lokationsbasierte Dienste bzw. Dienstkategorien hervorbringen wird, die es heute noch gar
nicht gibt - weswegen die aufgestellte Kategorisierung erweiterbar bleiben
soll. Zu beachten ist allerdings, dass die geschaffenen Klassen, wenn möglich,
disjunkt sein sollten.
In Anbetracht dessen wurde auf oberster Ebene versucht, eine Klassifizierung
zu erstellen, in die voraussichtlich auch die meisten zukünftigen Dienste
eingeordnet werden können. Zur Einordnung wurden folgende fünf Klassen
ausgewählt:
1. Output Services
2. Input Services
3. Storage and Computation Services
4. Device Control
5. Communication Services
Die Klassen eins und zwei trennen die Ausgabe- und die Eingabedienste,
wobei in erstere Kategorie alle Dienste einzuordnen sind, die dazu dienen,
Daten des Servicenutzers mittels eines Geräts auszugeben, das nicht in Besitz des Nutzers ist, ansonsten könnte der Dienst nicht als lokationsbasiert
bezeichnet werden. Die Eingabedienste stellen das Gegenteil dar, denn hier
wird ein fremdes Gerät zur Eingabe bzw. Erstellung von Daten benutzt. Da
24
Identifizierung und Klassifizierung von lokationsabhängigen
Diensten
jene Dienstkategorien gegensätzlich sind, sind diese beiden Klassen disjunkt.
Des Weiteren gibt es natürlich auch Services, die sowohl Eingabe- als auch
Ausgabecharakter besitzen, deswegen wurde als weitere Unterscheidung die
Kategorie Communication Services“ eingeführt. Selbstverständlich existie”
ren auch Dienste, bei denen weder die Ausgabe noch die Eingabe im Vordergrund steht, weswegen zusätzlich die Klassen Device Control“ und Storage
”
”
und Computation Services“ hinzugefügt wurden.
Im Folgenden wird jede der fünf Oberklassen einzeln genauer beschrieben,
begonnen wird mit der Klasse Output Services“. Die Taxonomie wird im
”
Text der Übersichtlichkeit halber immer nur in Teilstücken beschrieben; interessierte Leser, die die ganze Taxonomie sehen möchten, seien hiermit auf
den Anhang verwiesen, in dem die Taxonomie als Ganzes dargestellt ist.
4.1.1
Output Services
Auf der Ebene der Ausgabedienste wird zunächst in die drei Hauptkategorien Druckdienste ( Print Services“), Anzeigedienste ( Display“) und Ab”
”
spieldienste ( Play“) getrennt. In allen Fällen werden Daten ausgegeben,
”
im ersten Fall auf den Drucker, im zweiten auf einem Bildschirm bzw. Display und im dritten Fall über den Lautsprecher oder über Lautsprecher und
Bildschirm, wodurch sich die Trennung in diese drei Gruppen ergibt.
Auf der untergeordneten Ebene der Print Services“ wurde zunächst in Farb”
bzw. Schwarz-Weißdruck unterschieden, da eine Person in der Regel zunächst
auswählt, ob sie die Datei in Farbe ausdrucken möchte oder nicht. Dies ist
auch insofern von Bedeutung, als nicht jeder Drucker in der Lage ist, Bilder bzw. Text in Farbe zu drucken. Ferner wurde weiter unterschieden, ob
die entsprechende zu druckende Datei in einem ASCII-Format oder in einem Binärformat gespeichert ist. Diese Trennung ist den unterschiedlichen
Datentypen, die für die beiden Formate im XML-Schema verwendet werden, zu begründen. Zusammengefasst wurden die Druckdienste in folgende
Kategorien getrennt: Print Ascii Files“, Print Binary Files“, Print As”
”
”
cii Color“ und Print Binary Color“. Die Kategorie Display Document“
”
”
wurde dementsprechend ebenfalls in die Unterkategorien Display Ascii Do”
cument“ und Display Binary Document“ getrennt. Auf der untersten Ebene
”
der Taxonomie kann der Client schließlich den für ihn passenden Drucker
entsprechend des Formats der zu druckenden Datei aussuchen. In den untersten Klassen der Kategorie wird dazu in die speziellen Formate der Daten
unterschieden, so gibt es beispielsweise Drucker, die nur Dateien vom Typ
PS drucken können. Die letzte Differenzierung ist vor allem deswegen wichtig, da ein Dienstnutzer auf diese Weise schnell einen Dienst finden kann,
der in der Lage ist, seine Datei auszudrucken.
In der Kategorie Play“ wird zunächst in Play Audio“ und Play Video“
”
”
”
unterschieden, weil im ersten Fall nur der Lautsprecher involviert ist und im
zweiten Fall zusätzlich noch der Bildschirm als Ausgabegerät genutzt wird.
Identifizierung und Klassifizierung von lokationsabhängigen
Diensten
25
Da für die unterschiedlichen Audio- und Videoformate unterschiedliche Abspielsoftware existiert, werden auf der untersten Ebene ähnlich wie bei den
Druckdiensten die Play Services“ nach den Formaten getrennt, die sie ab”
spielen können.
Die Kategorie Nummer 3 ( Display“) wurde in die Unterklassen Display
”
”
Document“ und Display Image“ getrennt, da ein Bild und ein Dokument
”
unterschiedliche Anzeigeaspekte erfordern und für beide Zwecke verschiedene Anwendungssoftware existiert. Ebenso wie bei den beiden vorhergehenden Hauptkategorien wurde dann weiter nach den Formaten differenziert.
Output Services:
1. Print Services
1.1 Black-White Print Services
1.1.1 Print Ascii Files
1.1.1.1 Print PS
1.1.1.2 Print HPGL
1.1.2 Print Binary Files
1.1.2.1 Print GIF
1.1.2.2 Print JPEG
1.1.2.3 Print PCL
1.1.2.4 Print PDF
1.1.2.5 ...
1.1.2.6 Print PNG
1.2 Color Print Services
1.2.1 Print Ascii Color
1.2.1.1 Print PS
1.2.1.2 Print HPGL
1.2.2 Print Binary Color
1.2.2.1 Print GIF
1.2.2.2 Print PCL
1.2.2.3 Print PDF
1.2.2.4 ...
1.2.2.5 Print PNG
2. Play
2.1 Play Audio
2.1.1 Play MP3
2.1.2 Play WAV
26
Identifizierung und Klassifizierung von lokationsabhängigen
Diensten
2.1.3 ...
2.2 Play Video
2.2.1
2.2.2
2.2.3
2.2.4
2.2.5
Play
Play
Play
...
Play
MPEG1
MPEG2
MPEG4
Quicktime
3. Display
3.1 Display Document
3.1.1 Display ASCII Document
3.1.1.1 Display PS
3.1.1.2 Display HPGL
3.1.1.3 Display TXT
3.1.1.4 ...
3.1.2 Display Binary Document
3.1.2.1 Display DOC
3.1.2.2 Display PCL
3.1.2.3 Display PPT
3.1.2.4 ...
3.2 Display Image
3.2.1
3.2.2
3.2.3
3.2.4
4.1.2
Display GIF
Display JPEG
Display BMP
...
Input Services
In der Klasse der Eingabedienste ( Input Services“) sind nur Dienste ein”
zuordnen, die der reinen oder zumindest hauptsächlich der Dateneingabe dienen. Möglichkeiten, Daten einzugeben, ergeben sich beispielsweise
durch Sensoren, Videogeräte, Scanner oder Mikrophone. Sicher gibt es auch
die Möglichkeit, über ein Diskettenlaufwerk, ein CD-ROM/DVD-Laufwerk,
USB-Stick, Tastatur oder Maus Daten einzugeben. Dies wäre unter anderem dann der Fall, wenn man einen Laptop ohne DVD-Laufwerk besitzt,
man aber ein solches benötigt und vor Ort eines existiert. Ebenso könnte
ein Dienst ein Keyboard für PDA-Benutzer anbieten oder eine Maus für
Laptop-Besitzer. Es wurde in folgende Dienstkategorien aufgeteilt:
Identifizierung und Klassifizierung von lokationsabhängigen
Diensten
27
Input Services:
1. Scan
2. Record
2.1 Audio Input
2.2 Video Input
3. Sensor Input
3.1
3.2
3.3
3.4
3.5
3.6
4.1.3
Measure Temperature
Measure Ozon
...
DVD Input
Keyboard Input
Mouse Input
Storage and Computation Services
Der Dienst des Speicherns wurde, obwohl er auch der Kategorie Output Ser”
vices“ zugerechnet werden könnte, in eine eigene Klasse eingeordnet, da er
von dem normalen Benutzer nicht als Ausgabedienst wahrgenommen wird.
Ferner ist das Ziel eines Speichervorgang nicht nur die Ausgabe der Daten,
sondern vielmehr die kurzfristige oder langfristige bzw. permanente Speicherung von Daten. Neben den Speicherdiensten sollen auch alle weiteren
Dienste in dieser Kategorie eingeordnet werden, bei denen weder die Eingabe
noch die Ausgabe im Vordergrund stehen.
Storage and Computational Services
1. Save on external data mediums
1.1 Burn CD
1.2 Burn DVD
2. Computational Services
4.1.4
Device Control (Steuerungsdienste)
In dieser Gruppe sind alle Funktionen einzuordnen, die dazu dienen, Geräte
anzusteuern. Dies können Funktionen sein, wie beispielsweise das Ein- und
Ausschalten eines Geräts oder das Setzen von Parametern, die für die Steuerung der Geräte wichtig sind. So könnten beispielsweise auch Geräte mit
komplexen Funktionen angesteuert werden (beispielsweise die Ansteuerung
von Robotern), ohne vorher eine spezielle Programmiersprache dafür zu erlernen.
28
Konzeption einer WSDL-Taxonomie der Dienste
Device Control
1. Get-functions
2. Set-functions
4.1.5
Communication Services
Unter der Hauptkategorie Communication Services“ sind alle Dienste ein”
zuordnen, bei denen sowohl Eingabe als auch Ausgabe eine zentrale Rolle
spielen.
Communication Services
1. Chat
2. Message Services (Nachrichtendienste)
2.1 Fax
2.2 Mail
2.3 SMS
3. Conferences
3.1 Telephone Conference (over IP)
3.1.1 Dial In
3.1.2 Dial Out
3.2 Video Conference
3.2.1 Dial In
3.2.2 Dial Out
4.2
Konzeption einer WSDL-Taxonomie der Dienste
Bei der Entwicklung der WSDL-Taxonomie werden nicht nur ganze Dienste
betrachtet, sondern auch einzelne Funktionen der Dienste, die aufgrund von
Aspekten der Vererbung in der Taxonomie höher angeordnet werden, falls
sie für alle Kinderkategorien gleich sind. Auf diese Weise ergibt sich eine
bestimmte Struktur von Dateien auf den einzelnen Ebenen, wobei die tieferen Ebenen die Dateien der jeweils höher liegenden Ebene inkludieren. Auf
oberster Ebene der Klassifizierung (den fünf Hauptgruppen) werden keine
XML-Beschreibungen implementiert, da hier die Gruppen noch zu allgemein
sind, um Funktionen anzubieten, die für alle Untergruppen gelten.
Konzeption einer WSDL-Taxonomie der Dienste
4.2.1
29
Ausgabedienste
print Auf der Ebene der Druckdienste werden die Funktionen statusOfJob(), viewPrintJobs() und removeFromPrinterQueue() angeboten, da
sie als Standardfunktionen von fast allen Druckern realisiert werden. Die
wichtigste Funktion, die print-Funktion, wurde hingegen, aufgrund der vielen unterschiedlichen Formate der zu druckenden Dateien, auf eine tiefere
Ebene verlagert. Im Folgenden ist das WSDL-Fragment der Datei print.wsdl“
”
dargestellt, das die eben beschriebene Funktionalität realisiert:
<?xml version="1.0"?>
<definitions targetnamespace="http://com.test/print"
xmlns="http://www.w3.org/2003/06/wsdl"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsd1="http://www.icsy.de/xml/lawns/schemas/"
xmlns:tns="http://com.test/print">
<import location="print.xsd"
namespace="http://www.icsy.de/xml/lawns/schemas/">
<message name="printCharacteristics">
<part name="printID" type="xs:integer"/>
<part name="printerName" type="xs:integer"/>
</message>
<message name="statusOfPrintingJob">
<part name="status" type="xsd1:statusType"/>
</message>
<message name="viewPrintJobs">
<part name="printerName" type="xs:string"/>
</message>
<message name="queue">
<part name="printerName" type="xs:string"/>
<part name="printerQueue" type="xsd1:printerQueue"/>
</message>
<message name="removeFromPrinterQueue">
<part name="printerName" type="xs:string"/>
<part name="printID" type="xs:integer"/>
</message>
<message name="acknowledgementOfRemoval">
<part name="acknowledgement" type="xs:string"/>
</message>
<interface name="printing">
<operation name="statusOfJob">
<input message="tns:printCharacteristics"/>
<output message="tns:statusOfPrintingJob"/>
</operation>
<operation name="viewPrintJobs">
<input message="tns:viewPrintJobs"/>
<output message="tns:queue"/>
</operation>
<operation name="remove">
<input message="tns:removeFromPrinterQueue"/>
30
Konzeption einer WSDL-Taxonomie der Dienste
<output message="tns:acknowledgementOfRemoval"/>
</operation>
</interface>
</definitions>
Die WSDL-Datei definiert drei Operationen, die von dem Tag <interface>
zusammengefasst werden. Die erste Operation statusOfJob() erhält als
Eingabe den Namen des Druckers und die printID des Druckerjobs, nach
dessen Status sich der Client erkundigen möchte und liefert einen String als
Ausgabe, der den aktuellen Status des Jobs enthält. Des Weiteren gibt es
die Funktion viewPrintJobs(), die zur Ausgabe der ganzen Druckerschlange aufgerufen werden kann. Als Eingabeparameter benötigt diese Funktion lediglich den Namen des Druckers. Soll in Mehrbenutzersystemen die
Möglichkeit gegeben werden, dass ein Client nur seine eigenen Jobs sehen
kann, so müsste die Funktion um den Eingabeparameter Benutzername erweitert werden. Im Rahmen der vorliegenden Arbeit wurde die allgemeinere
Methode gewählt, da sie von jedem System ausgeführt werden kann. Ist dies
nicht gewünscht, so könnte eine Login-Funktion vorgeschaltet werden, damit wäre auch über die allgemeine Funktion ein Ausgeben nur der eigenen
Jobs möglich - gleiches gilt für die Löschfunktion. Die letzte der drei Funktionen dient dem Löschen eines Druckauftrages mit dem Eingabeparameter
printID und liefert als Ausgabe die Löschbestätigung, wobei der genaue
Text der Ausgabe hier offen gelassen wird.
Die Datei print.wsdl“ importiert eine XML-Schema-Datei namens print.xsd,
”
”
in der die Datentypen printerQueueEntry, printerQueue und statusType
wie folgt definiert werden:
<xsd:simpleType name="statusType">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="queued"/>
<xsd:enumeration value="printing"/>
<xsd:enumeration value="printed"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:complexType name="printerQueueEntry">
<xsd:sequence>
<xsd:element name="printID" type="xsd:integer"/>
<xsd:element name="status" type="tns:statusType"/>
<xsd:element name="fileName" type="xsd:string"/>
<xsd:element name="percentagePrinted" type="xsd:integer"/>
<xsd:element name="positionInPrinterQueue" type="xsd:integer"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="printerQueue">
<xsd:element name="printjob"
type="tns:printerQueueEntry" minOccurs="0"
maxOccurs="1000"/>
Konzeption einer WSDL-Taxonomie der Dienste
31
</xsd:complexType>
Der selbst definierte Datentyp statusType ist vom Typ string und kann die
drei Werte queued, printing und printed annehmen. printerQueueEntry
hingegen ist ein komplexer Datentyp, der aus den Elementen printID, percentagePrinted und positionInPrinterQueue vom Typ integer, dem Element fileName vom Typ string und dem Element status vom eben beschriebenen statusType besteht und der Anzeige der Charakteristiken eines
Durckerjobs dient. Der letzte in der Datei definierte Typ printerQueue besteht schließlich aus Null oder mehreren Elementen vom Typ printerQueueEntry, die maximale Anzahl liegt bei 1000. Diese Grenze wurde aber beliebig
gewählt und könnte auch eine andere Zahl darstellen. Der von XML-Schema
her auch mögliche Wert unbounded kann hingegen nicht gewählt werden, da
bei der Implementierung in Java auf die Datenstruktur Array zurückgegriffen werden soll und eine statische Grenze dabei die Realisierung vereinfacht.
Print Ascii Files, Print Binary Files Eine Ebene unter der Kategorie Print Services“ wird zunächst in Print Ascii Files“ und Print Binary
”
”
”
Files“ unterschieden, was sich durch den Unterschied bei der Datenübertragung ergibt. Ascii-Daten enthalten keine Kontrollzeichen, sondern sind reiner Text, wie beispielsweise die Formate PS oder HPGL. Eine solche Datei
kann direkt im Body einer SOAP Message enthalten sein oder als Attachment angehängt werden. Da SOAP Messages nur Daten im XML-Format
enthalten dürfen, kann eine binäre Datei hingegen nur als Attachment angehängt werden. Auf dieser Ebene wird die print()-Funktion angeboten,
wobei deren Realisierung in den beiden Gruppen sich nur dadurch unterscheidet, dass in dem einen Fall eine Datei in dem base64Binary-Format als
Attachment an eine SOAP Message angehangen wird und im anderen Fall
eine Ascii-Datei als String (entweder im Body oder als Attachment) zum
Drucker gesendet wird. Im Folgenden sind die WSDL-Dateien der beiden
Dienste dargestellt.
printascii.wsdl“:
”
<?xml version="1.0"?>
<definitions targetnamespace="http://com.test/printascii"
xmlns="http://www.w3.org/2003/06/wsdl"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:wsdl1="http://www.icsy.de/xml/lawns/print.wsdl"
xmlns:tns="http://com.test/printascii">
<import location="print.wsdl"
namespace="http://www.icsy.de/xml/lawns/print.wsdl">
<message name="printascii">
<part name="file" type="xs:string"/>
32
Konzeption einer WSDL-Taxonomie der Dienste
<part name="numberOfCopies" type="xs:integer"/>
</message>
<interface name="printing">
<operation name="printascii" parameterorder="?">
<input message="tns:printps"/>
<output message="wsdl1:printID"/>
</operation>
</interface>
</definitions>
printbinary.wsdl“:
”
<?xml version="1.0"?>
<definitions targetnamespace="http://com.test/printBinary"
xmlns="http://www.w3.org/2003/06/wsdl"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:wsdl1="http://www.icsy.de/xml/lawns/print.wsdl"
xmlns:tns="http://com.test/printBinary">
<import location="print.wsdl"
namespace="http://www.icsy.de/xml/lawns/print.wsdl">
<message name="printBinary">
<part name="file" type="xs:base64Binary"/>
<part name="numberOfCopies" type="xs:integer"/>
</message>
<interface name="printing">
<operation name="printBinaryFile">
<input message="tns:printBinary"/>
<output message="wsdl1:printID"/>
</operation>
</interface>
</definitions>
Die beiden Dateien enthalten jeweils eine Druckfunktion, die als Eingabe
die zu druckende Datei und einen Parameter für die Anzahl der Kopien
erhält und als Rückgabe eine ID für den Druckauftrag liefert. Eine Nachricht (<message>), die die printID beinhaltet, wurde bereits in der Datei print.wsdl definiert, weshalb diese in der Output Message referenziert
wird. Durch den Import der Datei print.wsdl stehen natürlich auch alle
Funktionen, die in dieser Datei definiert wurden, zur Verfügung.
Print Color Im vorgehenden Kapitel wurde bereits beschrieben, dass eine
Person in der Regel vor dem Druck entscheidet, ob in Schwarz-Weiß oder in
Farbe gedruckt werden soll. Deswegen wurden die Kategorien Print Ascii
”
Color“ und Print Binary Color“ eingeführt - in diesen Kategorien sind alle
”
Farbdrucker einzuordnen. Die print()-Funktion wurde für diesen Fall nur
um den weiteren Eingabeparameter Color“ vom Typ Boolean erweitert. Ist
”
der Parameter auf Eins gesetzt, so wird die Datei in Farbe ausgedruckt, ist er
Konzeption einer WSDL-Taxonomie der Dienste
33
auf Null gesetzt, so erfolgt der Ausdruck in Schwarz-Weiß bzw. Grautönen.
Hier wird exemplarisch nur die Datei printAsciiColor.wsdl gezeigt, da die
Datei printBinaryColor.wsdl sich nur bezüglich des Formats der Druckdaten von der anderen unterscheidet, was im Paragraph zuvor schon beschrieben und gezeigt wurde.
<?xml version="1.0"?>
<definitions targetnamespace="http://com.test/printAsciiColor"
xmlns="http://www.w3.org/2003/06/wsdl"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:wsdl1="http://www.icsy.de/xml/lawns/print.wsdl"
xmlns:tns="http://com.test/printAsciiColor">
<import location="print.wsdl"
namespace="http://www.icsy.de/xml/lawns/print.wsdl">
<message name="printAsciiColor">
<part name="file" type="xs:string"/>
<part name="numberOfCopies" type="xs:integer"/>
<part name="color" type="xs:boolean"/>
</message>
<interface name="printing">
<operation name="printps" parameterorder="?">
<input message="tns:printAsciiColor"/>
<output message="wsdl1:printID"/>
</operation>
</interface>
</definitions>
Einzelne Druckformate Auf der untersten Ebene der Kategorie Print
”
Services“ sind die Drucker nach den Formaten getrennt, die sie in der Lage
sind auszudrucken. Im Rahmen dieser Arbeit wurden keine weiteren formatoder druckerspezifischen Funktionen mehr hinzugefügt; diese Klassen importieren nur die Funktionalität der über ihnen liegenden Kategorien. Da die
WSDL-Dateien sehr ähnlich sind, werden hier nur zwei Dienste (drucken
einer PS-Datei in Schwarz-Weiß und drucken einer PDF-Datei in Farbe) exemplarisch beschrieben - in den Klammern ist jeweils angegeben, wie ein
Client über die einzelnen Kategorien zu dem gewünschten Service gelangt.
1. printPS.wsdl“ ( Print Services“ → Print Ascii“ → Print PS“)
”
”
”
”
<definitions targetnamespace="http://com.test/printPS"
xmlns="http://www.w3.org/2003/06/wsdl"
xmlns:tns="http://com.test/printPS">
<import printAscii.wsdl/>
</definitions>
2. printColorPDF.wsdl“ ( Print Services“ → Print Binary Color“ → Print
”
”
”
”
PDF“)
34
Konzeption einer WSDL-Taxonomie der Dienste
<definitions targetnamespace="http://com.test/printColorPDF"
xmlns="http://www.w3.org/2003/06/wsdl"
xmlns:tns="http://com.test/PrintColorPDF">
<import printBinaryColor.wsdl/>
</definitions>
Zur besseren Veranschaulichung ist an dieser Stelle die Vererbungs- bzw. Importhierarchie in einer Grafik dargestellt, um zusammenfassend einen Überblick über die Beziehungen zwischen den WSDL-Dateien zu erhalten. Der
Pfeil hat dabei folgende Bedeutung: a.[wsdl—xsd] → b.[wsdl—xsd] heißt,
dass die Datei b.wsdl (b.xsd) die Datei a.wsdl (a.xsd) importiert.
Print.
wsdl
Print.
xsd
PrintAscii.
wsdl
Print
PS.
wsdl
PrintBinary.
wsdl
PrintHPGL
.wsdl
PrintDOC.
wsdl
PrintPDF.
wsdl
Abbildung 4: Import-Hierarchie
Play Die Kategorie Play“ besitzt die beiden Unterkategorien Play Au”
”
dio“ und Play Video“, welche die Funktionen startPlaying(), stopPlaying()
”
und pause() und windToMinute gemeinsam umfassen. Sie sind in der Datei
play.wsdl“ wie folgt definiert:
”
<?xml version="1.0"?>
<definitions targetnamespace="http://com.test/play"
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:tns="http://com.test/play">
<message name="start">
<part name="file" type="base64Binary"/>
</message>
<message name="stop">
<part name="ID" type="xs:integer"/>
</message>
Konzeption einer WSDL-Taxonomie der Dienste
35
<message name="pause">
<part name="ID" type="xs:integer"/>
</message>
<message name="wind">
<part name="ID" type="xs:integer"/>
<part name="minute" type="xs:integer"/>
</message>
<message name="returnMessage">
<part name="sentence" type="xs:string"/>
</message>
<message name="handle">
<part name="ID" type="xs:integer"/>
</message>
<interface>
<operation name="startPlaying">
<input message="tns:play"/>
<output message="tns:handle"/>
</operation>
<operation name="stopPlaying">
<input message="tns:stop"/>
<output message="tns:returnMessage"/>
</operation>
<operation name="pause">
<input message="tns:pause"/>
<output message="tns:returnMessage"/>
</operation>
<operation name="windToMinute">
<input message="tns:wind"/>
</output message="tns:returnMessage"/>
</operation>
</interface>
</definitions>
Durch Ausführen der Funktion startPlaying() wird eine SOAP Message
mit der abzuspielenden Datei als Anhang zum Service gesendet, als Ausgabe erhält der Client eine ID, die seinen Abspielauftrag eindeutig identifiziert. Die Funktionen stopPlaying() und pause() erhalten beide als
Eingabeparameter die von der Funktion startPlaying rückgelieferte ID,
damit der Service den entsprechenden Auftrag identifizieren kann. Die Ausgabe ist im Fall der erfolgreichen Ausführung des Befehls ein Wert, der dies
bestätigt (dies könnte der Wert 1 oder die beispielsweise erneut die ID sein);
im Falle eines Fehlers enthält die returnMessage eine Fehlermeldung, die
angibt, warum der Befehl nicht ausgeführt werden konnte (z.B. falsches Format der Datei oder falsche Minutenangabe). Zusätzlich wird die Funktion
windToMinute() definiert, wobei der Eingabeparameter die Stelle in Minuten angibt, zu der das Video vor- oder zurückgespult werden soll.
In der Unterkategorie Play Audio“ steht zusätzlich zu den eben beschriebe”
nen Funktionen, die natürlich inkludiert werden, noch putFileInPlayQueue()
und removeFileFromPlayQueue() zur Verfügung. Damit besteht die Möglich-
36
Konzeption einer WSDL-Taxonomie der Dienste
keit, dass der Nutzer des Audioabspielers sich mehrere Dateien hintereinander anhören kann. Dies könnte z.B. dann der Fall sein, wenn die Person eine
Party in dem entsprechenden Raum gibt und nicht ständig damit beschäftigt
sein möchte, neue Lieder an den Service zu senden; die Auswahl kann vorher
getroffen werden. Die betreffende WSDL-Datei sieht wie folgt aus:
<?xml version="1.0"?>
<definitions targetnamespace="http://com.test/playAudio"
xmlns="http://www.w3.org/2003/06/wsdl/"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsd1="http://www.icsy.de/xml/lawns/schemas/"
xmlns:tns="http://com.test/playAudio">
<import location="playAudio.xsd"
namespace="http://www.icsy.de/xml/lawns/schemas/"/>
<import location="play.wsdl"
namespace="http://www.icsy.de/xml/lawns/play.wsdl"/>
<message name="putFileInQueue">
<part name="file" type="xs:base64Binary"/>
</message>
<message name="removeFileFromQueue">
<part name="fileName" type="xs:string">
</message>
<message name="acknowledgement">
<part name="file" type="xs:string"/>
<part name="acknow" type="xsd1:ackType"/>
</message>
<interface>
<operation name="putFileInPlayQueue">
<input message="tns:putFileInQueue"/>
<output message="tns:acknowledgement"/>
</operation>
<operation name="removeFileFromPlayQueue">
<input message="tns:removeFileFromQueue"/>
<output message="tns:acknowledgement"/>
</operation>
</interface>
</definitions>
Die Operation putFileInPlayQueue() dient dem Senden einer Datei zur
Eingliederung in die Abspielwarteschlange; sie bestätigt in einer Rückmeldung, dass die entsprechende Datei in die Warteschlange eingefügt wurde.
Möchte ein Client die Datei wieder aus der Schlange entfernen, so ruft er die
Funktion removeFileFromPlayQueue() mit dem Namen der Datei auf, die
gelöscht werden soll. Er erhält darauf eine Bestätigung, die angibt, welche
Datei gelöscht wurde. Der selbstdefinierte Datentyp ackType ist hierbei ein
String, der entweder die Zeichenkette file listet in queue“ oder file removed
”
”
from queue“ beinhaltet.
Konzeption einer WSDL-Taxonomie der Dienste
37
Display Auf oberster Ebene wird hier die allen Unterkategorien gemeinsame Funktion close(ID) angeboten, mittels derer eine geöffnete Datei wieder
geschlossen werden kann. Die eindeutige ID zur Identifizierung des Anzeigeauftrages wird von der entsprechenden display-Funktion, die eine Ebene
tiefer in der Hierarchieebene angeboten wird, zurückgeliefert. Ferner wird
die Funktion getResolution() angeboten, mit der die minimale und die
maximale Auflösung erfragt werden können, die der Dienst anbieten kann.
Die entsprechende WSDL-Datei sieht wie folgt aus:
<?xml version="1.0"?>
<definitions targetnamespace="http://com.test/display"
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:tns="http://com.test/display">
<message name="close">
<part name="ID" type="xs:integer">
</message>
<message name="resolution"/>
<message name="responseResolution">
<part name="minResolution" type="xs:string"/>
<part name="maxResolution" type="xs:string"/>
</message>
<interface>
<operation name="closeDocument">
<input message="tns:close"/>
</operation>
<operation name="getResolution">
<input message="tns:resolution"/>
<output message="tns:responseResolution"/>
</operation>
</interface>
</definitions>
Die Unterkategorie Display Document“ ist, in die Klassen Display As”
”
cii Document“ und Display Binary Document“ unterteilt, in denen dann,
”
entsprechend dem Format der Datei, die angezeigt werden soll, der entsprechende Dienst gesucht werden kann. Besitzt der Dienstnutzer beispielsweise
eine DOC-Datei, so würde sein Weg über die einzelnen Kategorien bis zur
Druckerauswahl wie folgt, lauten: Output Services → Display → Display Document → Display Binary Document → Display Doc. Sowohl die Datei dis”
playAsciiDocument.wsdl“ als auch die Datei displayBinaryDocument.wsdl“
”
bieten zwei Funktionen an, zum einen eine Operation zum Anzeigen der Datei (displayBinaryDocument() respektive displayAsciiDocument() und
zum anderen eine openDocumentWith()-Operation, mit der die Datei mit
einer anderen Software als dem dafür vorgegebenen Standard-Tool betrachtet werden kann. Exemplarisch wird hier die Datei DisplayBinaryDocu”
ment.wsdl“ dargestellt.
<?xml version="1.0"?>
38
Konzeption einer WSDL-Taxonomie der Dienste
<definitions targetnamespace="http://com.test/displayBinary"
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:tns="http://com.test/displayBinary">
<message name="displayBinary">
<part name="file" type="xs:base64Binary"/>
<part name="resolution" type="xs:string"/>
</message>
<message name="displayBinaryWith">
<part name="file" type="xs:base64Binary"/>
<part name="resolution" type="xs:string"/>
<part name="openWith" type="xs:string"/>
</message>
<message name="jobID">
<part name="ID" type="xs:integer"/>
</message
<interface>
<operation name="displayBinaryDocument">
<input message="tns:display"/>
<output message="tns:jobID"/>
</operation>
<operation name="displayDocumentWith">
<input message="tns:displayWith"/>
<output message="tns:jobID"/>
</operation>
</interface>
</definitions>
4.2.2
Input Services
Scan Wichtig ist in der Kategorie Scan“ natürlich die eigentliche scanFile”
Funktion. In der Regel gibt es zwar auch eine Vorschau-Funktion, aber auf
diese wurde hier verzichtet und statt dessen nur eine Funktion gewählt, mit
der ein Kunde die Auflösung (dpi) selbst einstellen kann. Ein Scan-Befehl
mit einer niedrigen Auflösung würde demnach einem Vorschauscan und ein
hoher Wert einem normalen Scanvorgang entsprechen. Als Ausgabe sendet
die Funktion die eingescannten Daten in Form einer Datei in dem gewünschten Datenformat zurück.
<?xml version="1.0"> <definitions name="ScanFile"
targetnamespace="http://com.test/scan"
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:xs="http://www.w3.org/2001/XMLSchema">"
xmlns:tns="http://com.test/scan">
<message name="scan">
<part name="resolution" type="xs:integer"/>
<part name="dataType" type="xs:string"/>
</message>
Konzeption einer WSDL-Taxonomie der Dienste
39
<message name="scannedFile">
<part name="file" type="base64Binary"/>
</message>
<interface>
<operation name="scanFile">
<input message="tns:scan"/>
<output message="tns:scannedFile"/>
</operation>
</interface>
</definitions>
Record Die Kategorie Record“ besitzt die zwei Unterklassen Audio In”
”
put“ und Video Input“ mit den gemeinsamen Funktionen: startRecording()
”
und stopRecording(). Als Szenario denkbar wäre hier zum Beispiel, dass
ein Nutzer ein Lied aufnehmen möchte, aber nicht über ein Mikrophon inklusive der entsprechenden Software verfügt - oder aber ein Client möchte
per Webcam ein Bild aufnehmen und dieses per Mail oder über einen anderen Dienst weitersenden. Die beiden Funktionen besitzen keine Eingabe,
da sie nichts anderes tun, als den Service zu starten und zu stoppen. Die
Funktion stopRecording() liefert als Ausgabe die aufgenommenen Daten,
die der Kunde dann beliebig weiter verwerten kann. Für den Datentyp den
die aufgenommene Datei besitzen soll, gibt es zwei Möglichkeiten: Entweder
wird die Auswahl des Datentyps in die Taxonomie integriert werden, das
heißt, dass der Kunde schon bei der Auswahl des Dienstes das Ausgabeformat berücksichtigt. Alternativ kann ein zusätzlicher Message-Parameter
eingeführt werden, mit dem die Auswahl getroffen werden kann. Im Rahmen
der vorliegenden Arbeit wurde die zweite Option verwendet und implizit vorausgesetzt, dass die Dienste in dem Verzeichnis, in dem sie publiziert sind,
angeben, welche Formate sie ausgeben können. Wäre dies nicht der Fall, so
müsste der Dienstnutzer, zunächst die möglichen Datenformate beim Service
erfragen.
<?xml version="1.0"?>
<definitions>
<message name="start">
<part name="dataType" type="xs:integer"/>
</message>
<message name="stop">
</message>
<message name="recordedFile">
<part name="file" type="xs:base64Binary"/>
</message>
<interface>
<operation name="startRecording">
<input message="tns:start"/>
</operation>
<operation name="stopRecording">
40
Konzeption einer WSDL-Taxonomie der Dienste
<input message="tns:stop"/>
<output message="tns:recordedFile"/>
</operation>
</interface>
</definitions>
Da auf der Ebene von Audio“ und Video Input“ keine weitere Funktiona”
”
lität hinzugefügt wird, sind die WSDL-Fragmente der beiden Klassen hier
nicht dargestellt.
Sensor Input An dieser Stelle wurde als lokationsbasiertes Szenario angedacht, dass ein Client die aktuelle Temperatur oder den Ozonwert an der für
ihn nächsten Messstation abfragen möchte. Auf dieser Ebene wird die Funktion measureValue() angeboten, ihre Ausgabe ist natürlich der gemessene
Wert.
<definitions>
<message name="measure"/>
<message name="measureResponse">
<part name="measuredValue" type="xs:integer"/>
<message>
<interface>
<operation name="measureValue">
<input message="tns:measure"/>
<output message="tns:measureResponse"/>
</operation>
</interface>
</definitions>
Für die Kategorien measure Temperature“ und measure Ozon“ werden
”
”
keine weiteren Funktionen eingeführt. Deswegen werden sie an dieser Stelle
auch nicht näher beschrieben. Möglich wären an dieser Stelle beispielsweise
Funktionen, die die Temperatur bzw. das Ozon mehrmals zu bestimmten
Zeiten am Tag messen und ein Array oder eine Liste von Zahlen ausgeben.
4.2.3
Storage and Computation Services
BurnCD Mittlerweile sind zwar fast alle neuen PCs und Laptops mit
Brenngeräten ausgestattet, aber noch ist nicht jeder in Besitz eines Brenners und muss deswegen auf einen Brenndienst zurückgreifen. Ganz abgesehen davon, gibt es mittlerweile viele kleine mobile Endgeräte, die ebenfalls keinen Brenner besitzen. Das Brennen ist natürlich ein Dienst der Kosten verursacht, aber diese werden an dieser Stelle nicht berücksichtigt. Zur
Berücksichtigung von Kosten und deren Abrechnung befinden sich einige
Anregungen in einem späteren Kapitel.
Konzeption einer WSDL-Taxonomie der Dienste
41
<?xml version="1.0"?>
<definitions targetnamespace="http://com.test/burn"
xmlns="http://www.w3.org/2003/06/wsdl/"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsd1="http://www.icsy.de/lawns/xml/burn.xsd"
xmlns:tns="http://com.test/burn">
<message name="burn"/>
<part name="filesToBurn" type="xsd1:listOfBase64Binary"/>
<part name="formatOfCD" type="xsd1:CDFormats"/>
<part name="titleOfCD" type="xs:string"/>
<part name="lengthOfFileandFolderNames" type="xsd1:ISO-Levels"/>
<part name="burnSpeed" type="xs:integer"/>
</message>
<message name="burnResult">
<part name="resultOfBurn" type="xs:string"/>
</message>
<interface name="burnCD">
<operation name="burnCD">
<input message="tns:burn"/>
<output message="tns:burnResult"/>
</operation>
</interface>
</definitions>
Die Kategorie BurnCD“ bietet genau eine Funktion an und zwar die Brenn”
funktion burnCD, die eine SOAP Message mit Parametern formatOfCD, das
angibt, ob es sich um eine Daten-CD, Audio-CD usw. handelt, den Namen der CD (titleOfCD), das ISO-Level, das u.a. die Länge der Dateiund Verzeichnisnamen bestimmt, die Brenngeschwindigkeit und natürlich
als Attachment die zu brennenden Daten. Es gibt mit Sicherheit noch weitere Parameter, die für einen Brennvorgang relevant sind, aber diese Arbeit
konzentriert sich auf die wichtigsten - weitere Funktionen mit unterschiedlichen Parametern können später beliebig hinzugefügt werden. Im Folgenden
sind die XML-Schema-Ausschnitte für die selbst definierten Typen listOfBase64Binary, CDFormats und ISOLevels dargestellt:
<xsd:complexType name="listOfBase64Binary">
<xsd:element name="file" type="xsd:base64Binary" minOccurs="1"
maxOccurs="1000"/>
</xsd:complexType>
<xsd:simpleType name="CDFormats">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="audioCD"/>
<xsd:enumeration value="dataCD"/>
<xsd:enumeration value="audioAndDataCD"/>
<xsd:enumeration value="VideoData"/>
<xsd:enumeration value="DataInImageFile"/>
</xsd:restriction>
42
Konzeption einer WSDL-Taxonomie der Dienste
</xsd:simpleType>
<xsd:simpleType name="ISOLevels">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="ISOLevel1"/>
<xsd:enumeration value="ISOLevel2"/>
</xsd:restriction>
</xsd:simpleType>
Die WSDL-Datei der Kategorie BurnDVD“ ist hier nicht dargestellt, da
”
nur der Parameter regionType als Eingabe zur Funktion burn hinzukommt,
ansonsten ändert sich nichts. Der regionType kann sechs verschiedene Werte
annehmen, je nach dem in welcher geographischen Region der Dienstnutzer
die DVD abspielen möchte.
4.2.4
Communication Services
An die Dienste Mail, Fax, Chat und SMS wurde auch gedacht, aber es
existieren bisher keine plausiblen lokationsbasierten Anwendungsszenarien
für diese Dienste. Deswegen werden an dieser Stelle nur die Kategorien
Telephone Conference“ und Video Conference“ beschrieben, wobei je”
”
weils zwei verschiedene Konferenztypen unterschieden werden können: Dial
”
In“ und Dial Out“. Im ersten Fall meldet eine Person, in der Regel der
”
Konferenzführer, die Konferenz bei einem entsprechenden Dienst mit PINNummer und Datum des Tages, an dem sie stattfinden soll, an. Die PINNummer und das Datum werden anschließend in irgendeiner Form (Mail,
mündlich, ...) den Konferenzteilnehmern bekannt gemacht, die sich dann an
dem entsprechenden Tag mittels der PIN-Nummer zur Konferenz einwählen
können. Im gibt eine Person unmittelbar vor Beginn der Konferenz oder
länger im Voraus die Teilnehmer und deren Rufnummern an. Die Teilnehmer
werden dann automatisch angerufen. Selbstverständlich bietet diese Konferenzform ebenfalls die Möglichkeit, Personen durch Angabe von Namen und
IP-Adresse nachträglich (auch nach Beginn der Konferenz) einzuladen und
Personen von der Konferenz auszuschließen.
Bezüglich der WSDL-Dateien gibt es zwar keinen Unterschied zwischen einer
Telefon- und Videokonferenz, allerdings stellt es einen großen Unterschied
dar, ob der Kunde nun eine Video- oder eine Telefonkonferenz stattfinden
lassen möchte. Deswegen wurde für die beiden Arten von Konferenzen eigene Gruppen in der Taxonomie eingeführt. Für eine Videokonferenz wäre
beispielsweise folgendes Szenario denkbar: Eine Person möchte oder soll per
Konferenz ein Vorstellungsgespräch führen und besitzt dazu nicht die nötige
Ausrüstung.
Dial In Bei Verwendung dieser Variante der Konferenz werden die Funktionen registerConference(), joinConference(), closeConference(),
Konzeption einer WSDL-Taxonomie der Dienste
43
lockConference() und leaveConference(), angeboten. Letztere drei Funktionen benötigen als Eingabe nur die PIN-Nummer, während ihre Ausgabe
leer ist. Mit der Operation registerConference() erfragt der Dienstnutzer, ob eine Konferenz an einem bestimmten Tag zu bestimmter Uhrzeit
mit der selbst festgelegten PIN-Nummer stattfinden kann. Der Service sendet daraufhin eine Bestätigung, die die PIN-Nummer enthält.
<?xml version="1.0"?>
<definitions targetnamespace="http://com.test/dialIn"
xmlns="http://www.w3.org/2003/06/wsdl"
xmlns:xs="http://www.w3.org/2001/XMLSchema">"
xmlns:xsd1="http://www.icsy.de/lawns/xml/conference.xsd"
xmlns:tns="http://com.test/dialIn">
<import location="conference.xsd"
namespace="http://www.icsy.de/lawns/xml/conference.xsd">
<message name="register Conference">
<part name="dateOfConference" type="xs:date"/>
<part name="time" type="xs:time"/>
<part name="PINNumber" type="xsd1:PINNumber"/>
</message>
<message name="conferenceID">
<part name="PINNumber" type="xsd1:PINNumber"/>
</message>
<message name="join">
<part name="PINNumber" type="xsd1:PINNumber"/>
<part name="IPNumberOFConference" type="xsd1:IPAddress"/>
</message>
<interface name="telephoneConferenceInterface">
<operation name="registerConference">
<input message="tns:registerConference"/>
<output message="tns:conferenceID"/>
</operation>
<operation name="joinConference">
<input message="tns:join"/>
</operation>
<operation name="leaveConference">
<input message="tns:conferenceID"/>
</operation>
<operation name="closeConference">
<input message="tns:conferenceID"/>
</operation>
<operation name="lockConference">
<input message="tns:conferenceID"/>
</operation>
</interface>
</definitions>
In der WSDL-Datei wird die XML-Schema-Datei conference.xsd“ inklu”
diert, die die beiden einfachen Datentypen IPAddress und PINNumber definiert.
44
Konzeption einer WSDL-Taxonomie der Dienste
<xsd:simpleType name="IPAddress">
<xsd:restriction base="xsd:string">
<xsd:pattern value="\d{3}.\d{3}.\d{3}.\d{3}"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="PINNumber">
<restriction base="integer">
<xsd:length value="6"/>
</restriction>
</xsd:simpleType>
Dial Out Für diese Art von Telefon- oder Videokonferenz werden fünf verschiedene Funktionen angeboten. Die erste, registerConference(), erhält
als Eingabe das Datum und die Uhrzeit, zu der die Konferenz stattfinden soll
und die IP-Adressen der Teilnehmer. Zu gegebenem Zeitpunkt startet dann
der Dienstanbieter die Konferenz, indem er die Nachricht startConference()
an alle gemeldeten Teilnehmer sendet. Die Konferenz kann folglich beginnen. Soll nachträglich jemand zur Konferenz eingeladen oder von der Konferenz ausgeschlossen werden, so können die Funktionen invitePerson()
und excludeFromConference() aufgerufen werden. Beide Funktionen erhalten die IP-Adresse des Teilnehmers als Eingabe. Bei Aufruf der Funktion
invitePerson() baut der Service eine Verbindung zu der einzuladenden
Person und lädt die Person zur Teilnahme ein. Mit der letzten Operation
closeConference() ist es, wie der Name bereits verrät, möglich die Konferenz zu beenden. Die betreffende WSDL-Datei sieht wie folgt aus:
<?xml version="1.0"?>
<definitions targetnamespace="http://com.test/dialOut"
xmlns="http://www.w3.org/2003/06/wsdl"
xmlns:xs="http://www.w3.org/2001/XMLSchema">"
xmlns:xsd1="http://www.icsy.de/lawns/xml/conference.xsd"
xmlns:tns="http://com.test/dialOut">
<import location="conference.xsd"
namespace="http://www.icsy.de/lawns/xml/conference.xsd">
<message name="startConference">
<part name="IPAddresssOfparticipants" type="xsd1:listOfIPAddresses"/>
<part name="date" type="xs:date"/>
<part name="time" type="xs:time"/>
</message>
<message name="invite">
<part name="newParticipant" type="xsd1:IPAddress"/>
</message>
<message name="invitationToConference">
</message>
<message name="exclude">
<part name="IPAddressParticipant" type="xsd1:IPAddress"/>
</message>
Konzeption einer WSDL-Taxonomie der Dienste
45
<message name="close">
</message>
<interface name="telephoneConferenceInterface">
<operation name="registerConference">
<input message="tns:startConference"/>
</operation>
<operation name="startConference"/>
<output message="tns:invitationToConference"/>
</operation>
<operation name="invitePerson">
<input message="tns:invite"/>
<output message="tns:invitationToConference"/>
</operation>
<operation name="excludeFromConference">
<input message="tns:exclude"/>
</operation>
<operation name="closeConference">
<input message="tns:close"/>
</operation>
</interface>
</definitions>
In dieser Datei wird neben IPAddress der zusätzliche Datentyp listOfIPAddresses benutzt, der ganz einfach aus einer Liste von IP-Adressen besteht. Dieser Typ ist in der Datei conference.xsd“ definiert, in der auch
”
die beiden Datentypen der Variante Dial In“ definiert sind. Da beide den
”
Datentyp IPAddress verwenden, wurde aus Gründen der Wiederverwendbarkeit nur eine Schema-Datei und nicht zwei verschiedene erstellt.
46
4.3
Weitere wichtige Aspekte bezüglich lokationsbasierter
Dienste
Weitere wichtige Aspekte bezüglich lokationsbasierter
Dienste
Web Services ermöglichen zwar eine relativ einfache Integration beliebiger
Anwendungen, aber im globalen Netzverkehr sind auch Aspekte wie Sicherheit, Vertrauenswürdigkeit von Nachrichten, Kodierung sensitiver Daten (beispielsweise Kreditenkartennummer), Workflow-Unterstützung usw.
wichtig. Die Basisfunktionalität eines Web Services alleine reicht also nicht
aus, es sind unterstützende Zusatzfunktionalitäten erforderlich. Stellvertretend werden an dieser Stelle die Aspekte Autorisierung, Authentisierung und
Abrechnung näher beleuchtet.
4.3.1
Autorisierung
Für die Frage der Autorisierung (Ist eine Person berechtigt, den Service zu
nutzen?) bietet der Standard SOAP eine Möglichkeit. Im Header kann ein
Kindelement <authentication> definiert werden, in dem der Benutzername
und das Passwort des Dienstnutzers eingegeben werden können [KUWÖ].
Wird zusätzlich noch das Attribut mustUnderstand auf 1 gesetzt, so liefert
der Dienst bei nicht bekanntem Benutzernamen oder falschem Passwort eine
SOAP-Nachricht mit einer Fehlermeldung an den Dienstnutzer zurück. Eine
Fehlermeldung gibt der Dienstanbieter ebenfalls aus, wenn er die Informationen im Header nicht verarbeiten kann. Ein entsprechendes Beispiel sieht
wie folgt aus (vgl. [KUWÖ]):
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlSOAP.org/SOAP/envelope">
<SOAP-ENV:Header>
<auto:authentication
xmlns:auto="URI-Namespace"
mustUnterstand="1">
<auto:user>userName</auto:user>
<auto:password>password</auto:password>
</auto:authentication>
</SOAP-ENV:Header>
<!-- SOAP Body -->
</SOAP-ENV:Envelope>
Das Element <authentication> muss als direktes Kindelement vom Hea”
der“ seinen eigenen Namespace besitzen, der hier wahlweise auf auto gesetzt
wurde.
Die Autorisierung muss nicht durch den Empfänger der Nachricht bzw.
Dienst selbst verarbeitet werden. Dies kann ebenfalls durch eine dritte Partei ausgeführt werden, wobei die Zwischenstationen, über die die Nachricht
läuft, bevor sie ihr Ziel beim Empfänger erreicht, auch Nodes genannt werden. Ein Node kann die Nachricht einfach weiterreichen oder als ein Actor die Autorisierung für den Dienstanbieter übernehmen [KUWÖ]. Nach
Weitere wichtige Aspekte bezüglich lokationsbasierter
Dienste
47
der Durchführung der entsprechenden Aktion entfernt der Actor die für ihn
bestimmte Anweisung aus dem Header oder ersetzt sie durch einen neuen
Eintrag und schickt die Nachricht an den Empfänger oder an den nächsten Node weiter. Um dieses Verhalten zu erreichen, muss das Kindelement
<authentication> wie folgt erweitert werden:
<auto:authentication xmlns:auto="irgendeineURI"
mustUnderstand="1"
SOAP-ENV:Actor="URI des Actors">
<auto:user>userName</auto:user>
<auto:password>password</auto:password>
</auto:authentication>
Aber eine Autorisierung ist nicht nur über den Standard SOAP realisierbar, auch HTTP Authentication ist geeignet, um zu testen, ob ein Benutzer
autorisiert ist, um den Dienst zu nutzen [FRA99]. Eine weitere Möglichkeit
zur Autorisierung bieten Zertifikate, sie können mit der SOAP-Nachricht
übermittelt werden. Der Dienst oder ein Dritter müssten dann das Zertifikat verifizieren, um festzustellen, ob ein Nutzer berechtigt ist, den Dienst
zu nutzen. Zertifikate können aber auch dazu dienen, den Absender einer
Nachricht eindeutig zu identifizieren (Authentizität).
4.3.2
Authentizität
Unter Authentizität ist laut Duden die Echtheit bzw. Rechtsgültigkeit zu
verstehen – im Rahmen dieser Arbeit wurde Authentizität als das Faktum
definiert, dass der Empfänger der Nachricht weiß, dass die Nachricht in der
Tat von der Person stammt, die als Absender der Nachricht angegeben ist.
Mit anderen Worten, der Empfänger der Nachricht kann den Absender eindeutig identifizieren. Für diesen Zweck existieren SOAP-Erweiterungen, die
IBM entwickelt hat. Dies ist zum einen ein Erweiterungselement namens
¡SOAP-Authorization¿ das die Möglichkeit bietet, Zertifikate in der SOAPMessage zu inkludieren [NASKSR]. Zum anderen die Möglichkeit der digitalen Signatur [BAR02], die die im nichtelektronischen Bereich übliche Unterschrift ersetzt. Die Signaturen, die dabei auf die Daten im XML-Format
angewendet werden, sind selbst in XML geschrieben bzw. kodiert. Es kann
in drei Formen von XML Signaturen unterschieden werden [NASKSR]:
• enveloped Signature (Die Signatur ist in dem XML-Dokument, das es
signieren soll, selbst als Kindelement enthalten)
• enveloping Signature (In diesem Fall ist der Inhalt der signiert werden
soll, in einem <Object>-Element der Signatur selbst enthalten.)
• detached Signature (Die Signatur signiert Daten, die außerhalb des
¡Signature¿-Elements stehen, d.h. die Signatur und die zu signierenden Daten sind voneinander getrennt. Hierbei ist es nicht zwingend
48
Weitere wichtige Aspekte bezüglich lokationsbasierter
Dienste
erforderlich, dass die Daten und die Signatur in zwei unterschiedlichen
Dateien gespeichert sind.)
Auch in diesem Bereich wurde in SOAP eine Möglichkeit geschaffen, die das
Problem mit Hilfe der Verwendung von XML-basierten digitalen Signaturen
adressiert. Hier ist ein Code-Beispiel für diese Technik dargestellt, das sich
an ein einfaches Beispiel von der Organisation W3C anlehnt, das unter der
URL http://www.w3.org/TR/xmldsig-core/“ zu finden ist:
”
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/envelope/">
<SOAP-ENV:Header>
<SOAP-SEC:Signature
xmlns:SOAP-SEC="http://schemas.xmlsoap.org/soap/security/"
SOAP-ENV:actor="Some-URI"
SOAP-ENV:mustUnderstand="1">
<ds:Signature Id="MyFirstSignature"
xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<ds:CanonicalizationMethod
Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
<ds:SignatureMethod
Algorithm="http://www.w3.org/2000/09/xmldsig#dsa-sha1"/>
<ds:Reference URI="#Body">
<ds:Transforms>
<ds:Transform
Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n20010315"/>
</ds:Transforms>
<ds:DigestMethod
Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<ds:DigestValue>
j6lwx3rvEPO0vKtMup4NbeVu8nk=
</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>MC0CFFrVLtRlk=...</ds:SignatureValue>
<ds:KeyInfo>
<ds:KeyValue>
<ds:DSAKeyValue>
<P>...</P><Q>...</Q><G>...</G><Y>...</Y>
</ds:DSAKeyValue>
</ds:KeyValue>
</ds:KeyInfo>
</ds:Signature>
</SOAP-SEC:Signature>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
...
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Weitere wichtige Aspekte bezüglich lokationsbasierter
Dienste
49
Dieses Beispiel definiert eine XML-basierte digitale Signatur, die die Daten
des SOAP-Envelope signiert. Das <SOAP-SEC:Signature>-Element besitzt
folgende Kindelemente: <SignedInfo>, <SignatureValue> und <KeyInfo>.
Das erste Element, <SignedInfo>, ist recht komplex und enthält in seinen Kindelementen die Information, mit welchen Algorithmen die Signatur erzeugt wird, und definiert, welche Daten signiert werden. Das Element <SignatureValue> enthält den Wert der erzeugten Signatur. Auf
die zu signierenden Daten wird mit dem Element <Reference> verwiesen. Das <KeyInfo>-Element ist optional und enthält Informationen, die der
Empfänger der Nachricht nutzen kann, um die Signatur zu validieren. Im obigen Beispiel enthält das letztgenannte Element einen öffentlichen Schlüssel;
andere Möglichkeiten sind beispielsweise Zertifikate oder Namen, die einen
Schlüssel bzw. ein Schlüsselpaar identifizieren. Eine solche Signatur kann
zusätzlich mit einem Zeitstempel versehen werden, aber dies wird hier nicht
dargestellt. Auf diese Beispiele wird nun nicht näher eingegangen, für weitergehende Informationen wird auf [BAR02] verwiesen.
4.3.3
Abrechnung
Dienste verursachen in der Regel Kosten, die der Dienstnutzer zahlen muss.
Die Höhe der Kosten kann ein Kriterium sein, nach dem der Nutzer sich
einen Dienst aussucht, deswegen sollten die Kosten des Dienstes in dem
Verzeichnis, aus dem der Kunde sich den Dienst aussucht vermerkt sein.
Bei komplizierteren Web Services mit längeren Transaktionen kann es sogar
sinnvoll sein, einen Vertrag über die Art, Entstehung und Zusammensetzung
der Kosten abzuschließen. Die Kostenabrechnung eines Dienstes muss nicht
vom Anbieter selbst durchgeführt werden, sie kann auch durch einen Dritten vorgenommen werden. Der Web Service könnte beispielsweise nach der
Nutzung die Kosten an einen Dritten melden, der an den Client dann die
Rechnung stellt.
Eine Realisierungsmöglichkeit der Abrechnung könnte beispielsweise darin
bestehen, dass der Kunde seine Bankverbindung oder Kreditkartennummer
in einer SOAP-Message mitteilt, dies erfordert allerdings, dass die Nachricht
oder zumindest der Teil der SOAP-Message, der die sensitiven Informationen
enthält, kodiert wird. Zur Verschlüsselung von Daten existiert eine Empfehlung der Standardisierungsorganisation W3C namens XML Encrypti”
on Syntax and Processing“. Das entsprechende Dokument definiert einen
Prozess zur Verschlüsselung der Daten und der Repräsentation dieser verschlüsselten Daten in XML [IMA02]. Die Daten können dabei beliebig sein;
das Ergebnis ist ein XML Encrytion Element, das die verschlüsselten Daten entweder beinhaltet oder referenziert. Werden einzelne Elemente eines
XML-Dokumentes verschlüsselt, so stehen die verschlüsselten Daten an der
Stelle, wo die XML-Elemente stehen würden. Im Folgenden ist ein Beispiel
dafür dargestellt; es ist der Quelle [IMA02] übernommen. Zunächst sind die
50
Weitere wichtige Aspekte bezüglich lokationsbasierter
Dienste
Daten unkodiert dargestellt, anschließend kodiert:
<?xml version=’1.0’?>
<PaymentInfo xmlns=’http://example.org/paymentv2’>
<Name>John Smith</Name>
<CreditCard Limit=’5,000’ Currency=’USD’>
<Number>4019 2445 0277 5567</Number>
<Issuer>Example Bank</Issuer>
<Expiration>04/02</Expiration>
</CreditCard>
</PaymentInfo>
----gleiches XML-Dokument mit kodierten Daten:
<?xml version=’1.0’?>
<PaymentInfo xmlns=’http://example.org/paymentv2’>
<Name>John Smith</Name>
<EncryptedData Type=’http://www.w3.org/2001/04/xmlenc#Element’
xmlns=’http://www.w3.org/2001/04/xmlenc#’>
<CipherData>
<CipherValue>A23B45C56</CipherValue>
</CipherData>
</EncryptedData>
</PaymentInfo>
Weitere Informationen zu diesem Standard sind unter der Quelle [BAR02]
verfügbar.
Beispielhafte Implementierungen für Web Services
5
51
Beispielhafte Implementierungen für Web Services
In diesem Abschnitt werden beispielhafte Implementierungen für die Druckdienste Print(), viewPrinterQueue(), statusOfJob() und deleteJobFromQueue() beschrieben. Bei der Implementierung wurde das Sun Java Web
Service Developer Pack (JWSDP) in den Versionen 1.1 und 1.2 benutzt. Ursprünglich sollte nur mit der Version 1.2 gearbeitet werden. Da aber die bei
der Implementierung des Druckdienstes benutzte Schnittstelle JAXM beim
Übergang von Version 1.1 auf 1.2 nicht mehr im Developer Pack enthalten
ist, wurde zunächst auf die Version 1.1 zurückgegriffen. Im Laufe der Erstellung der vorliegenden Arbeit erschien eine neue Version der JAXM API
(JAXM 1.1.2), die dann zur Implementierung des Beispiels benutzt wurde.
Als Implementierungssprache für die Beispiele wurde Java verwendet und
das Druckersystem CUPS unter SUSE Linux angesprochen. Im folgenden
werden zunächst das JWSDP und die bei der Implementierung benutzten
Schnittstellen des Pack beschrieben; anschließend wird auf die beiden Beispiele eingegangen. Unter anderem wird der Aspekt beleuchtet, ob die in
Kapitel 4.2 erstellten WSDL-Fragemente genutzt werden können.
5.1
5.1.1
Java Web Service Developer Pack
Kurzbeschreibung des Pack
Das Java Web Service Developer Pack ist eine von SUN Microsystems entwickelte Software, mit deren Hilfe Java-Entwickler Web Services, XML- und
Web-Applikationen erstellen, testen und einsetzen kann. Die aktuelle Version
ist das JWSDP1.2 und besteht aus folgenden Komponenten (http://www.java.sun.com):
• JavaServer Faces (JSF) v1.0 EA4
• XML and Web Services Security v1.0 EA
• Java Architecture for XML Binding (JAXB) v1.0.1
• Java API for XML Processing (JAXP) v1.2.3
• Java API for XML Registries (JAXR) v1.0.4
• Java API for XML-based RPC (JAX-RPC) v1.1 EA
• SOAP with Attachments API for Java (SAAJ) v1.2 EA
• JavaServer Pages Standard Tag Library (JSTL) v1.1 EA
• Java WSDP Registry Server v1.0 05
52
Java Web Service Developer Pack
• Ant Build Tool 1.5.2
• Apache Tomcat v5 development container
• Ws-I Supply Chain Management Sample Application 1.0 EA
Im Folgenden werden die in der vorliegenden Arbeit verwendeten Komponenten SAAJ und JAX-RPC des JWSDP 1.2 und die API JAXM genauer
beschrieben.
5.1.2
JAX-RPC
Das JAX-RPC (Java API für XML-basierte Remote Procedure Calls) ist
eine Java-Schnittstelle, die einen XML-basierten Zugriff auf Remote Procedure Calls unterstützt, wodurch ein Aufruf einer Methode in verteilten
Systemen ermöglicht wird, zum Beispiel in dem Fall, dass Dienstnutzer und
Dienst auf verschiedenen Plattformen arbeiten. Als XML-basiertes Nachrichtenaustauschformat wird der Standard SOAP verwendet (siehe Kapitel
3.1); aktuell in der Spezifikation SOAP 1.1. Obwohl das JAX-RPC eine JavaSchnittstelle ist, setzt dies nicht voraus, dass sowohl der Nutzer als auch der
Anbieter eine Java-Plattform einsetzen. Schließlich werden die Nachrichten
im XML-Format SOAP ausgetauscht und beide Seiten können jede beliebige Technik nutzen, mittels derer die Daten einer Nachricht entpackt und
verwertet werden können, und das JAX-RPC ist nur eine Möglichkeit dafür.
Zurzeit gibt es zwei Ansätze, um einen Web Service, seine Dienstbeschreibung und die entsprechenden Applikationen mittels JAX-RPC zu erstellen:
• Top Down – Bei diesem Ansatz wird zuerst die Dienstbeschreibung,
die WSDL-Datei, erstellt, die dann benutzt wird, um automatisch
stub“- oder skeleton“-Code zu generieren, der dann mit der Funk”
”
tionalität ausgefüllt wird.
• Bottom Up – Bei diesem Ansatz werden erst die Klassen bzw. der
Applikationscode programmiert, der zur automatischen Generierung
einer WSDL-Datei genutzt wird.
Die Vorgehensweise, um einen Web Service mit dem Bottom-Up-Ansatz zu
generieren, sieht wie folgt aus:
• Begonnen wird mit der Programmierung des Servicecodes, der aus
einem Interface und einer Klasse, die das Interface implementiert, besteht. Zusätzlich muss für jeden selbstdefinierten Datentyp eine eigene
Java-Klasse oder ein Java Bean geschrieben werden.
• Anschließend muss der betreffende Code kompiliert werden, dazu und
für die folgenden Befehle kann das Ant-Tool1 benutzt werden. In diesem Fall lautet der Befehl: ant compile.
1
Entwicklungstool für Java von der Apache Software Foundation.
Java Web Service Developer Pack
53
• Danach kann mittels des Befehls ant package des Ant-Tool oder mit
alternativen Befehlen (unter Unix jar) eine WAR-Datei mit unten
angegebener Struktur erstellt werden.
• Als Nächstes wird das wsdeploy-Tool des Service Pack benutzt (ant
process-war), um eine (deployable) WAR-Datei zu erstellen. Das
Tool erzeugt ebenfalls die ties“ für den Service und die WSDL-Datei.
”
Das wsdeploy-Tool benötigt als Eingabe eine Datei namens jaxrpc”
ri.xml“, in der ein oder mehrere <endpoint>-Elemente definiert werden müssen. Das <endpoint>-Element besitzt Attribute, die den Namen des Endpunktes festlegen, den Namen, unter dem der Service
angezeigt werden soll, den Namen des Interfaces und den Namen der
Klasse. Mittels des <endpoint-Mapping>-Elements wird angegeben,
unter welcher URL der Endpunkt erreichbar sein soll.
• Waren die vorhergehenden Schritte erfolgreich, so kann der Dienst mittels des Befehls ant deploy oder mit dem Tomcat2 deployed werden.
• Danach erfolgt der Aufruf von wscompile zur Generierung der stubs“
”
für den Client (zur Eingabe benötigt der Befehl die Datei config.xml“,
”
in der die WSDL-Datei spezifiziert wird).
• Zum Schluss wird ein Client implementiert, der den Service benutzt.
Bei Verwendung des Top-Down-Ansatzes sieht die Vorgehensweise wie folgt
aus:
• Da die WSDL-Beschreibung vorliegt, wird mit dem Aufruf des Befehls
wscompile begonnen. Dieser kann benutzt werden, um Code sowohl
für die Client-Seite als auch für die Server-Seite zu generieren. Zusätzlich wird abhängig vom Inhalt der Datei config.xml“ ein WSDL”
Dokument oder eine Service-Endpunkt-Definition generiert. Ebenso
wird noch ein model-file erstellt, eine XML-Datei, die Informationen
über den Service enthält. Dieses model-file ist so aufgebaut, dass es
vom wsdeploy-Tool benutzt werden kann.
• Anschließend muss eine Klasse geschrieben werden, die den Service
implementiert, Klassen für die selbstdefinierten Datentypen sind bereits von der WSDL-Datei generiert worden. Ist die Implemetierung
abgeschlossen, muss der Code kompiliert und eine WAR-Datei erzeugt
werden.
• Mit dem Befehl wsdeploy wird danach eine deployable WAR-Datei
erzeugt, die per ant deploy oder Tomcat deployed wird (Aufruf von
wsdeploy unter Nutzung des model-file).
2
Tomcat bezeichnet eine Ablaufumgebung für serverseitiges Java (Servlet) und die Java
Server Pages (JSP) von der Apache Software Foundation.
54
Java Web Service Developer Pack
• Als Abschluss wird ein Client zum Testen des Dienstes implementiert.
Eine WAR-Datei ist eine JAR-Datei (Java-Archiv) mit folgender Verzeichnisstruktur:
WEB-INF/
WEB-INF/classes (kompilierte Service- oder Client-Klasse)
WEB-INF/src (Source-Code des Services oder Client)
WEB-INF/web.xml
WEB-INF/jaxrpc-ri.xml (falls JAX-RPC Web Service)
*.html (falls JAXM und HTTP-Servlet: HTML-Datei, die das HTTPServlet startet)
Bei den Ansätzen ist zu beachten, dass nicht alle Datentypen des XMLSchemas bzw. Java-Codes von den aktuellen Software-Tools, die die automatische Generation durchführen, unterstützt werden. Da in der vorliegenden
Arbeit das Sun Java Web Service Developer Pack benutzt wurde, gelten die
nachfolgenden Ansätze auch nur für das JWSDP.
Nicht unterstützte Datentypen beim Top-Down-Ansatz Zunächst
ist in diesem Abschnitt anzumerken, dass das JWSDP 1.2 noch nicht die
aktuelle Version WSDL 1.2 unterstützt, sondern nur die Version WSDL 1.1.
Da zur Erstellung der WSDL-Taxonomie die Version 1.2 benutzt wurde,
werden hier zur Verständlichkeit der Beispiele die Unterschiede zwischen
den beiden Versionen, soweit relevant, aufgelistet.
• Das Element <portType> wurde in <interface> umbenannt. Das
<interface>-Element erhielt zusätzlich die Funktionalität vererbar
zu sein.
• Das <port>-Element wurde in <endpoint> umbenannt.
• Das von WSDL 1.1 unterstütze Überladen von Operationen wurde in
der Version 1.2 entfernt.
• In der Version 1.1 diente das <import>-Element dazu, andere Dateien
(WSDL oder XML-Schemata) unabhängig vom verwendeten targetNamespace zu importieren. Waren die Zielnamensräume verschieden,
so wurde das targetNamespace angegeben; waren sie hingegen gleich,
wurde das targetNamespace-Attribut nicht gesetzt. Diese Funktionalität wird, wie in Kapitel 3.2.2 beschrieben, nun auf die beiden Elemente <include> und <import> aufgeteilt.
Des Weiteren werden Typ- bzw. Elementdefinitionen des XML-Schemas,
die die Attribute minOccurs und maxOccurs verwenden, von dem JWSDP
Java Web Service Developer Pack
55
bei der automatischen Generierung von Code-Teilen aus WSDL nicht unterstützt. Folgender in Kapitel 4.2 definierter komplexer Datentyp ist demnach nicht möglich:
<xsd:complexType name="printerQueue">
<xsd:element name="printJob"
type="tns:printerQueueEntry" minOccurs="0" maxOccurs="1000"/>
</xsd:complexType>
Statt dessen muss der komplexe Datentyp als Array definiert werden, das
im Fall des Beispiels wie folgt aussieht:
<complexType name="printerQueue">
<complex Content>
<restriction base="soap11-enc:Array">
<sequence>
<attribute ref="soap11-enc:arrayType"
wsdl:arrayType="tns:PrinterQueueEntry[]">
</sequence>
</restriction>
</complexContent>
</complexType>
Unterstützte Datentypen beim Bottom-Up-Ansatz Im Gegensatz
zum Top-Down-Ansatz werden hier nicht die Datentypen beschrieben, die
nicht unterstützt werden, sondern die Typen aufgelistet, die unterstützt werden. Möchte ein Dienstanbieter erst den Dienst in Java programmieren und
dann mittels des JWSDP die Dienstbeschreibung automatisch erstellen, so
muss er darauf achten, dass die Java-Datentypen unterstützt werden. Folgende primitive Datentypen werden von der aktuellen JAX-RPC-Version
unterstützt (siehe Beschreibung [ARM03]):
• boolean
• byte
• double
• float
• int
• long
• short
Unterstützt werden ebenfalls ein- und mehrdimensionale Arrays von den
eben genannten primitiven Datentypen. Ferner sind strukturierte Typen,
sogenannte Value Types“, möglich, wobei allerdings nachstehende Regeln
”
eingehalten werden müssen:
56
Java Web Service Developer Pack
• Die Klasse muss einen öffentlichen Default-Konstruktor besitzen.
• Die Klasse darf weder direkt noch indirekt das Interface java.rmi.Remote implementieren.
• Die einzelnen Komponenten des Datentyps müssen von JAX-RPC unterstützte Datentypen sein.
• Der Value Type“ kann aus öffentlichen, privaten oder geschützten
”
(public, private oder protected) Feldern bestehen, wobei gilt:
– Ein öffentliches Feld darf nicht als final oder transient deklariert werden.
– Ein nicht-öffentliches Feld muss mindestens eine get- und eine
set-Methode definieren.
Alle JavaBeans, die den gleichen oben genannten Regeln für Klassen entsprechen und jeweils eine get- und eine set-Methode für jede der Eigenschaften
(bean properties) besitzen, werden unterstützt.
Ebenfalls können die in der folgenden Tabelle dargestellten Klassen verwendet werden, die das java.util.Collection-Interface implementieren.
java.util.Collection
Subinterface
List
Map
Set
Implementation Interface
ArrayList
LinkedList
Stack
Vector
HashMap
Hashtable
Properties
TreeMap
HashSet
TreeSet
Erstellung des Client Ein Client, der JAX-RPC benutzt, kann eine Operation eines Service-Endpunktes auf drei verschiedene Arten aufrufen:
1. Die Operation kann durch ein lokales Objekt, einen sogenannten stub“,
”
aufgerufen werden.
2. Ein dynamischer Proxy“ kann benutzt werden, um die Operation
”
aufzurufen.
3. Die Operation kann mittels des Dynamic Invocation Interface (DII)“
”
dynamisch aufgerufen werden.
57
Java Web Service Developer Pack
Im Folgenden werden diese drei Varianten beschrieben, wobei die erste am
ausführlichsten erläutert wird, da diese bei der Implementierung des JAXRPC-Beispiels verwendet wird.
Die erste Variante wird benutzt, wenn der Dienstnutzer weiß, welche Operation er aufrufen möchte und wie er sie aufrufen muss, das heißt, dass er auch
weiß, welche Parameter die Funktion benötigt. Der stub“ dient der Verein”
fachung von remote calls“, denn der Client sendet seinen Operationsaufruf
”
an den stub“ (der das entfernte Objekt lokal repräsentiert) und damit be”
steht für ihn kein Unterschied zu einem lokalen Aufruf. Der stub“ übersetzt
”
dann den Funktionsaufruf in das richtige Format und sendet ihn zum Server. Dieser Prozess wird auch als marshalling“ bezeichnet. Auf Serverseite
”
existiert ein tie“, der das Gegenstück zum stub“ auf Clientseite darstellt.
”
”
Der tie“ entpackt die Information ( auch unmarshalling“ genannnt) und
”
”
ruft dann die Funktion auf dem Objekt aus. Für die Antwort wird der
Prozess umgekehrt. Der stub“ kann mittels des Befehls wscompile“ des
”
”
JWDP automatisch von einer WSDL-Beschreibung oder der Definition eines Service-Endpunktes generiert werden [ORMA02].
Client
3. Runtime maps
call to SOAP
message
Server
10. Runtime extracts
SOAP Message
4. Runtime extracts
SOAP Message
HTTP
JAX-RPC
Runtime
JAX-RPC
Runtime
SOAP
Message
11. Stub
returns
response
2. Stub
converts call
Tie
12. Application
gets response
Client
Applikation
8. Tie converts
response
5. Tie makes
call on Web
Service
Stub
1. Application
makes RPC
call
9. Runtime maps
response to SOAP
message
6. Web
Service
processes
request
7. Web Service
returns response
Web
Service
Abbildung 5: Use stub“ to make remote call“. Quelle: The JavaTM Web
”
”
Service Developer Pack, Part 2 [ORMA02].
Die zweite Variante benötigt keinen im voraus generierten Code ( stubs“),
”
denn zur Laufzeit wird dynamisch ein proxy“ erzeugt, in dem die getPort”
Funktion der Schnittstelle javax.xml.rpc.Service aufgerufen wird. Als
Eingabe benötigt, die getPort()-Funktion lediglich den Namen des Ports
und das kompilierte Interface des Endpunktes; Ausgabe der Operation ist
eine dynamisch erstellte Implementierung des Service-Endpunktes. Diese
Implementierung benutzt das java.lang.reflect.Proxy Objekt, um die
58
Java Web Service Developer Pack
Objekte zu erstellen (einen entsprechenden SOAP-Envelope in diesem Fall),
die per java.lang.reflect.InvocationHandler.invoke() an den Dienst
geschickt werden [CHJE03]. Für weitere Informationen zur Funktionsweise
von dynamischen Proxys wird auf die J2SE Dokumentation von Sun Microsystems verwiesen, die unter http://java.sun.com/j2se/ zu finden ist.
Kennt der Dienstnutzer zur Laufzeit weder den Namen der Funktion, die
er aufrufen möchte, noch die Anzahl, Art und Namen der Parameter, so
kann er die Variante drei nutzen. Hier wird die Methode auf Client-Seite auf
einem call-Objekt ausgeführt. Die Datenstruktur eines Call-Objektes spiegelt die Struktur einer WSDL-Datei wieder; es besitzt Attribute für folgende
Informationen einer WSDL-Datei [ORMA02]:
• Name der Operation
• Interface des Service-Endpunktes
• Eigenschaften der Anbindung (wie die SOAP Action Header URI der
SOAP-Anbindung) über HTTP
• Name, Typ und Modus der Ein- und Ausgabeparameter
• Typ des Rückgabewertes
Wird die Service-Endpunkt-Implementierung von einer WSDL-Datei generiert, werden diese Attribute mit Hilfe der WSDL-Datei gesetzt. Alternativ
kann ein Client das Call-Objekt auch mittels set-Methoden konfigurieren,
wie dies in einem Beispiel im JWSDP, Part 2 dargestellt ist [ORMA02]. Ein
ausführliches Beispiel beschreiben auch Chappell und Jewell in ihrem Buch
Java Web Services [CHJE03] (S. 168-171). Ferner unterstützt das DII nicht
nur Request/Response-Nachrichten, sondern ist ebenfalls in der Lage asynchrone Nachrichten zu versenden. Auf diese Variante wird nun nicht näher
eingegangen, da sie in den Beispielen nicht verwendet wird.
5.1.3
JAXM und SAAJ
JAXM steht für Java API for XML Messaging“ und unterstützt mehre”
re Industriestandards, unter anderem SOAP und ebXML [NASKSR]. Die
Schnittstelle JAXM ermöglicht Java-Anwendungen einen Informationsaustausch mittels XML-Format über das Intranet oder Internet, wobei sowohl
das Versenden von synchronen (request/response) als auch von asynchronen Nachrichten (one-way messages) unterstützt werden. Diese API wurde
speziell für den Austausch von Dokumenten entwickelt und ist damit besonders auf Operationen im B2B (Business-to-Business) fokussiert, wo es
häufig erforderlich ist, Dokumente auszutauschen [ARM03]. Im Gegensatz
zum JAX-RPC wird bei dieser API keine spezielle Funktion/Methode aufgerufen, sondern ein XML-Dokument zum Service geschickt und vorausgesetzt,
Java Web Service Developer Pack
59
dass der Service den Inhalt des Dokuments versteht und daraufhin die entsprechende Funktion aufruft. Ebenso ist die Antwort des Services auch nicht
die Ausgabe einer Funktion sondern eine Nachricht, die die ausführende Applikation erstellt hat. In einem solchen Szenario ist es also sehr wichtig, dass
sowohl Client als auch Service die Bedeutung der Nachrichten verstehen, die
an sie gesendet werden.
Diese API besteht aus zwei verschiedenen Paketen [ARM03]:
• javax.xml.soap
• javax.xml.messaging
Erstgenanntes Paket gibt es auch getrennt von dem zweiten und heißt dann
SAAJ (Soap Attachment API for Java) und ist im Gegensatz zu JAXM in
dem Developer Pack 1.2 enthalten. Die JAXM API war nur bis zur Version
1.1 des Developer Pack integriert und wurde dann aus dem Pack ausgelagert.
Das Paket javax.xml.soap stellt Interfaces und Klassen zur Verfügung, mit
deren Hilfe der Programmierer eine SOAP Message und eventuell vorhandene Attachments erstellen und handhaben kann. Des Weiteren ermöglicht dieses Paket dem Client das Versenden von point-to-point“ response/request
”
Nachrichten. Unter einer point-to-point“-Verbindung ist in diesem Szena”
rio zu verstehen, dass die Nachricht von einem Client direkt an den Service
gesendet wird. Request/Response heißt in diesem Fall, dass die Ausführung
des Client-Codes nach Aufruf der entfernten Methode so lange gestoppt
wird, bis der Client die Antwort auf seine Anfrage erhält. Viele der Namen
der Klassen und Interfaces dieses Pakets entsprechen den Elementen einer
SOAP-Nachricht, weswegen der Programmierer stets das Bild einer SOAPMessage vor Augen haben sollte, wenn er eine solche mit Hilfe der Interfaces
und Klassen dieses Pakets zusammenstellt oder handhabt.
Um eine One-Way-Nachricht zu versenden oder einen Message Provider zu
benutzen, wurde das zweite Paket, das javax.xml.messaging entwickelt.
Der Message Provider übernimmt die Übermittlung und das Routing der
Nachrichten. Die Benutzung eines Providers zum Versenden und Empfangen von Nachrichten ist optional und deswegen wird bei der Erstellung eines
JAXM-Servlets in solche unterschieden, die einen Provider nutzen, und solche, die keinen nutzen. Der Service erweitert das JAXM-Servlet und muss
eine Methode onMessage() besitzen, die aufgerufen und abgearbeitet wird,
sobald eine Nachricht eintrifft. Wird kein Provider verwendet, so muss der
Client nicht in einem Web Container laufen. Ein Service, der auf der API
SAAJ basiert, also nur auf dem ersten Paket, können der Service und der
Client alternativ die Klasse HTTP-Servlet erweitern. In diesem Fall besitzt
der Client eine doGet()-Methode, die eine Nachricht über HTTP versendet,
woraufhin die doPost()-Methode des Services aufgerufen wird, die wiederum die onMessage()-Methode aufruft.
60
Beispielimplementierungen für Druckdienste
Soll das JAXM-Servlet benutzt werden, um einen Request/Response-Service
zu erstellen, so muss das JAXM-Servlet das Interface ReqRespListener implemetieren. Sollen hingegen asynchrone Nachrichten verschickt werden, so
muss die Klasse das Interface OneWayListener implementieren.
Auf die einzelnen Klassen und Interfaces wird an dieser Stelle aber nicht
näher eingegangen, ihre Verwendung wird an den nachfolgenden Beispielen
klar gemacht und kommentiert. Ferner wird auf das allgemeine JWSDPTutorial [ARM03] und das JWSDP-Tutorial Part 2 [ORMA02] verwiesen.
5.2
Beispielimplementierungen für Druckdienste
In diesem Kapitel wird die Implementierung eines Druckdienstes zum Drucken der Formate PS, HTML und XML auf einem Schwarz-Weiß-Drucker als
Web Service beschrieben. Die Druckfunktion, wurde mittels der API JAXM
implementiert, da diese API, wie bereits erwähnt, speziell für den Transport von Dokumenten entwickelt wurde und sich demnach sehr gut für den
Druckdienst eignet. Schließlich muss der Client zum Drucken, seine Datei
bzw. sein Dokument an den Web Service versenden. Des Weiteren wurde ein
Druckmanagementdienst implementiert, der Funktionen zum Anzeigen der
Druckerschlange bzw. der Druckjobs, zum Löschen des Druckauftrages und
zur Anzeige des Status eines Druckjobs anbietet. Für den Druckmanagementdienst wurde die API JAX-RPC verwendet, da diese Funktionen keine
Dokumente sondern Parameter als Eingabe erwarten, mit denen eine Funktion aufgerufen wird, um eine bestimmte Aktion auszuführen und/oder Information zu erhalten. Unter anderem wurde für letztere Funktionen auch das
JAX-RPC ausgewählt, weil diese API Funktionen besitzt, die die Verwendung der WSDL-Dateien aus der Taxonomie ermöglichen, sofern der TopDown-Ansatz verwendet wird. In der vorliegenden Arbeit werden nur exemplarisch Teile ausprogrammiert und beschrieben, da eine vollständige Implementierung nicht gefordert war. In Abbildung 6 sind die oben beschriebe-
JAXM
SOAP
MSG
(HTTP)
print()
JAXM
PrintService
JAX-RPC
SOAP
MSG
(HTTP)
statusOfJob(), remove(),
viewPrinterQueue()
JAX-RPC
PrintManagement
Service Requestor
Service Provider
Abbildung 6: Druckdienst Realisierung
Beispielimplementierungen für Druckdienste
61
nen Implementierungsentscheidungen veranschaulicht. Der drei Funktionen
umfassende Web Service PrintManagement wurde sowohl mit dem BottomUp-Ansatz, als auch mit dem Top-Down-Ansatz, der eine den Dienst beschreibende WSDL-Datei benutzt, erstellt. Zwar führen beide Ansätze zum
gleichen Ziel, aber sie unterscheiden sich in einigen Punkten, weswegen hier
beide Ansätze in groben Zügen dargestellt sind.
5.2.1
PrintManagement – Bottom-Up-Ansatz
Bei diesem Ansatz werden zunächst die Schnittstelle des Services und eine
Klasse, die diese Schnittstelle implementiert, erstellt. Die Schnittstelle heißt
PrintIF.java und der Quellcode sieht wie folgt aus:
package print;
import
import
import
import
java.rmi.Remote;
java.rmi.RemoteException;
print.PrinterQueueEntry;
print.StatusType;
public interface PrintIF extends Remote {
public StatusType statusOfJob (int printID, String printerName)
throws RemoteException;
public PrinterQueueEntry[] viewPrinterQueue (String printerName)
throws RemoteException;
public String remove (int printID, String printerName)
throws RemoteException;
}
Die Schnittstelle PrintIF deklariert die drei Funktionen statusOfJob(),
viewPrinterQueue() und remove(), wobei sie das Interface Remote erweitert, da diese drei Funktionen Methoden auf entfernten Objekten aufrufen;
dementsprechend muss ebenso eine RemoteException abgefangen werden.
Die Funktionen remove() und statusOfJob() benötigen neben der ID des
Druckjobs noch den Namen des Druckers, falls der Druckdienst mehrere
Drucker besitzt, die über unterschiedliche Namen angesprochen werden.
Anschließend müssen die Schnittstelle und die einzelnen Funktionen implementiert werden. Dies wird in der Klasse PrintImpl.java getan; sie ist
nachfolgend dargestellt.
package print;
import
import
import
import
java.io.*;
java.rmi.RemoteException;
print.PrinterQueueEntry;
print.StatusType
public class PrintImpl implements PrintIF, java.rmi.Remote, Serializable {
62
Beispielimplementierungen für Druckdienste
public StatusType statusOfJob(int printID, String printerName) {
// implementation of the function statusOfJob()
}
public PrinterQueueEntry[] viewPrinterQueue(String printerName) {
// implementation of the function viewPrinterQueue()
}
public String remove(int printID, String printerName) {
// implementation of the function remove()
}
}
Die Funktion statusOfJob() erhält als Eingabe die ID des Druckauftrags
sowie den Namen des Druckers und gibt den Status des Druckauftrags in
Form eines selbstdefinierten Datentyps zurück, der die Werte printed“,
”
printing“ oder queued“ annehmen kann. Da der Status eines Druckauf”
”
trages in der Ausgabe des Linux CUPS (Common Unix Print System) nicht
angegeben wird, wurde diese Funktion wie folgt implementiert: Zur Laufzeit
wird die Funktion lpq zur Ausgabe der Druckerschlange aufgerufen und deren Ausgabe dann zeilenweise eingelesen und überprüft wird, ob eine dieser
Zeilen in der Spalte printID, den Wert der gesendeten ID enthält. Folglich
wird nur zwischen den printed“ und queued“ unterschieden.
”
”
Die zweite Funktion gibt die zur Laufzeit des Programms akutelle Druckerschlange zurück. Dazu wird zunächst die Ausgabe des lpq-Befehls in eine
Datei gelesen, die dann geparst wird, um die notwendigen Informationen zu
entnehmen und in einem PrinterQueueEntry-Array zu speichern, das von
der Laufzeitumgebung des JAX-RPC serialisiert wird und in den SOAPBody der Nachricht an den Client im XML-Format eingefügt wird.
Die letzte Funktion löscht einen Druckauftrag mit einer bestimmten printID auf einem bestimmten Drucker. Da ein Auftrag bereits ausgedruckt sein
könnte oder die printID falsch, wird an dieser Stelle gegebenenfalls der
Error-Stream abgefangen und ausgegeben.
Für den Typ StatusType muss eine eigene Klasse geschrieben werden, die
teilweise nachstehend dargestellt ist. Diese muss sich an die Einschränkungen
von JAX-RPC bezüglich der Datentypen richten und wird in dem nachfolgenden Unterkapitel mit der automatisch generierten Klasse vom Top Down
Ansatz verglichen.
package print;
import java.io.*;
public class StatusType implements Serializable {
private String value;
Beispielimplementierungen für Druckdienste
63
public static final String queuedString = queued“;
”
public static final String printingString = printing“;
”
public static final String printedString = printed“;
”
public static final String queued = new String( queuedString);
public static final String printing = new String( printingString);
public static final String printed = new String( printedString);
public static final StatusType queued = new StatusType( queued);
public static final StatusType printing = new StatusType( printing);
public static final StatusType printed = new StatusType( printed);
public StatusType() { }
protected StatusType(String val) {
this.value = val;
}
public String getValue() {
return value;
}
public void setValue(String s) {
if (s== queuedString) value= queued;
if (s== printingString) value= printing;
if (s== printedString) value= printed;
}
// Hier können wie bei der automatisch generierten Klasse
// noch die Funktionen fromValue(), fromString(), toString(),
// equals() und hashCode() implementiert werden
...
}
Da sich die Unterschiede zur der automatisch generierten Klasse beim TopDown-Ansatz nur am Anfang befinden, ist die Klasse StatusType aus Platzgründen hier nicht vollständig dargestellt. Der Name der Variablen value
wurde hierbei beibehalten, anstatt sie z.B. in status umzutaufen, damit die
Beispiele direkt vergleichbar sind.
Bei der Erstellung der Klasse PrinterQueueEntry wurde ebenfalls darauf
geachtet, dass sie die Bedingungen eines JAX-RPC-Typs entspricht. Aus
diesem Grund werden für die Attribute der Klasse nur einfache unterstützte
Datentypen verwendet. Alternativ hätte an dieser Stelle für das Attribut
status statt des Typs String auch der selbstdefinierte Typ StatusType
gewählt werden können. Die Klasse sieht wie folgt aus:
package print;
import java.io.*;
64
Beispielimplementierungen für Druckdienste
public class PrinterQueueEntry implements Serializable {
private int printID;
private String status;
private String fileName;
private int percentagePrinted;
private int positionInPrinterQueue;
public printerQueueEntry(int prID, String stat,
String name, int percentage, int position) {
this.printID = prID;
this.status = stat;
this.fileName = name;
this.percentagePrinted = percentage;
this.positionInPrinterQueue = position;
}
public printerQueueEntry() { }
// passende get- und set-Methoden müssen an dieser
// Stelle für jedes Attribut der Klasse definiert
// werden...
...
}
Für diese von JAX-RPC unterstützten Datentypen werden von jedem JAXRPC konformen System automatisch Serialisierer und Deserialisierer zum
Übersetzen von Javaobjekten in das XML-Format und umgekehrt (marshalling, unmarshalling) zur Verfügung gestellt (siehe Abbildung 7). Für andere
Java
Type
Serializer
XML
XML
Deserializer
Java
Type
JAXRPC
Service
Java
Client
Java
Type
Deserializer
XML
XML
Serializer
Java
Type
Abbildung 7: Serializers and Deserializers. Quelle: [MAG03], S. 388.
Objekte muss der Programmierer sich seine Serialisierer und Deserialisierer
selbst schreiben. Diese sind im Anschluss spätestens zur Laufzeit des Programmes in der TypeMappingRegistry des JAX-RPCs zu registrieren, damit zum Übersetzen darauf zurückgegriffen werden kann. Die TypeMappingRegistry ist eine Tabelle mit sogenannten TypeMapping -Einträgen, die bestimmten encoding styles zugeordnet werden [MAG03]. Ein TypeMappingEintrag besteht aus folgenden Attributen: Java-Typ (Klasse), SerializerFactory, DeserializerFactory und dem entsprechenden XML-Typ. Zur Laufzeit
des Web Services schaut die JAX-RPC Routine in dieser Tabelle nach, damit sie weiß, wie die entsprechenden Datentypen serialisiert, deserialisiert
Beispielimplementierungen für Druckdienste
65
und kodiert werden.
Da die durch JAX-RPC zur De-/Serialisierung bereitgestellten Interfaces
(Serializer, Deserializer, SerializationContext und DeserializationContext)
keine Methoden enthalten, die die Funktionalität zur Serialisierung und Deserialisierung realisieren, wird oder muss der Anwendungsentwickler sich seine eigenen De-/Serialisierer als Sub- oder Unterklassen der zuvor genannten
Interfaces programmieren. In der Regel sind die auf diese Weise vorgenommenen Implementierungen an die jeweilige Laufzeitumgebung angepasst.
Sind sind folglich spezifisch für eine bestimmte Implementierung und daher nur für diese verwendbar [MAG03].
Der Rückgabewert der Funktion viewPrinterQueue() ist ein Array von
dem Typ PrinterQueueEntry und damit kein Array eines der unterstützten Standardtypen. Dennoch wird der Befehl wscompile“ Serialisierer für
”
den Datentyp generieren, was für alle in der WSDL-Datei definierten Datentypen möglich ist. Für die Serviceseite ist es wichtig, dass die Klasse,
die den selbstdefinierten Datentyp definiert, das Interface Serializable implementiert. Ist dies der Fall, so werden durch den Befehl wsdeploy“ auto”
matisch die benötigten Serialisierer (Serialisierer und Deserialisierer befinden
sich dabei in der gleichen Klasse) generiert und in der TypeMappingRegistry
registriert. Die einzige Einschränkung, die bei dieser Art von selbstdefinierten Datentypen existiert, ist die Tatsache, dass nur ein statischer Client
über seinen stub“ automatisch auf diese Serialisierer zurückgreifen kann,
”
ein dynamischer Proxy oder ein DII-Client würde einen Serialisierungsfehler
melden.
Zur Fertigstellung des Web Services wurden die Funktionen des JWSDP
und das ant-Tool, wie in Kapitel 5.1.2 beschrieben, benutzt. Zum Testen des
Web Services wurde ein statischer Client verwendet. Durch das automatische
Erstellen der stubs“ für den Client ergibt sich eine weitere Variante der
”
Klasse Statustype. Sie besitzt zwei öffentliche Konstruktoren und jeweils
eine get- und eine set-Methode. Sie ist nachfolgend dargestellt:
// This class was generated by the JAXRPC SI, do not edit.
// Contents subject to change without notice.
// JAX-RPC Standard Implementation (1.1, build EA-R39)
package print.stubs;
public class StatusType {
protected java.lang.String value;
public StatusType() {
}
public StatusType(java.lang.String value) {
this.value = value;
}
66
Beispielimplementierungen für Druckdienste
public java.lang.String getValue() {
return value;
}
public void setValue(java.lang.String value) {
this.value = value;
}
}
5.2.2
PrintManagement - Top Down Ansatz
Zunächst wurde untersucht, ob die in Kapitel 4.2 erstellte WSDL-Datei (siehe Seite 29)
von dem JAX-RPC verwendet werden kann. Da die WSDL-Datei den Beschränkungen
der unterstützten Datentypen unterliegt, die bereits in diesem Kapitel beschrieben wurden, musste die Datei von WSDL Version 1.2 auf die Version 1.1 angepasst und ein Array für den komplexen Typ PrinterQueueEntry definiert werden. Des Weiteren wurden
zur Vervollständigung der Dienstbeschreibung zusätzliche WSDL-Elemente (<binding>,
<endpoint>, <service>) und Erweiterungselemente für die Anbindung an SOAP über
HTTP angefügt. Die resultierende WSDL-Datei kann im Anhang eingesehen werden.
Mittels des wscompile-Tools, das als Eingabe eine Datei namens config.xml, die auf die
WSDL-Datei verweist, benötigt, erstellte das JWSDP automatisch Klassen für die Datentypen StatusType und PrinterQueueEntry inklusive der für diese Klassen benötigten Serialisierer und Deserialisierer, damit die Datentypen in XML transformiert werden können
und umgekehrt. Ferner wurde für jede der drei Funktionen in einer Klasse die Requestund Responsestruktur beschrieben, damit die SOAP-Nachricht entsprechend aufgebaut
bzw. entpackt werden kann. Letztendlich wurde für den Client ein stub“ und für den
”
Dienstanbieter ein tie“ erstellt sowie das Interface PrintIF. Die Klasse StatusType“ wird
”
”
nachfolgend teilweise dargestellt, da sie sich durch die beim Bottom Up Ansatz erstellte
unterscheidet.
// This class was generated by the JAXRPC SI, do not edit.
// Contents subject to change without notice.
// JAX-RPC Standard Implementation (1.1, build EA-R39)
package print.stubs;
public class StatusType implements java.io.Serializable {
private java.lang.String value;
public static final String queuedString = queued“;
”
public static final String printingString = printing“;
”
public static final String printedString = printed“;
”
public static final java.lang.String queued =
new java.lang.String( queuedString);
public static final java.lang.String printing =
new java.lang.String( printingString);
public static final java.lang.String printed =
new java.lang.String( printedString);
public static final StatusType queued = new StatusType( queued);
public static final StatusType printing = new StatusType( printing);
public static final StatusType printed = new StatusType( printed);
Beispielimplementierungen für Druckdienste
67
protected StatusType(java.lang.String value) {
this.value = value;
}
public java.lang.String getValue() {
return value;
}
...
}
Der Unterschied zu den beiden beim Bottom-Up-Ansatz erstellten Klassen
ist sofort sichtbar, denn zum einen wird kein öffentlicher Konstruktor definiert und des anderen existiert für die Variable value keine set-Methode.
Statt dessen besitzt die Klasse einen geschützten Konstruktor, der außerhalb der Klasse nicht aufgerufen werden kann. Damit entspricht die Klasse nicht mehr den für einen JAX-RPC-Typ geforderten Eigenschaften und
würde beim Versuch, die Klasse als Eingabe für den Bottom-Up-Ansatz zu
verwenden, einer Fehlermeldung herbeiführen.
Im Anschluss wurde eine Klasse geschrieben, die das Interface implementiert. Sie unterscheidet sich nicht von der Klasse, die beim Bottom Up Ansatz
implementiert wurde und ist deswegen hier weder dargestellt noch beschrieben. Anschließend wurde wie in Kapitel 5.1.2 beschrieben weiterverfahren.
Zum Testen des Web Services wurde der gleiche statische Client wie beim
Bottom-Up-Ansatz verwendet.
5.2.3
JAXM-basierter PrintService
In diesem Kapitel wird der Web Service PrintService mittels der API JAXM
implementiert. Wie bereits zuvor beschrieben, müssen sich der Dienstanbieter und der Client über die Bedeutung (Semantik) der Nachrichten einig
sein, wenn sie erfolgreich miteinander kommunizieren möchten. Deswegen
wird zum besseren Verständnis des Beispiels in der folgenden Beschreibung
zwischen Client-Code und Service-Code, passend zum Szenario eines Druckaufrufs, hin und her gewechselt. Begonnen wird an dieser Stelle mit dem
Code des Client und dem Aufbau der SOAP-Message, die der Client an den
Service sendet, um einen Druckauftrag auszulösen.
Zunächst wird in der Main-Methode des Client ein SOAPConnection-Objekt
erzeugt, mit dessen Hilfe die SOAP-Message an den Dienst gesendet werden
kann. Anschließend wird ein SOAPFactory-Objekt erstellt, das dazu dient,
Name-Objekte zu erstellen, die der SOAP-Spezifikation 1.1 entsprechen. Die
letztgenannten Objekte werden benötigt, um den SOAP-Body der Nachricht
mit Information zu füllen. Die Code-Zeilen sehen wie folgt aus:
SOAPConnectionFactory soapConnectionFactory =
SOAPConnectionFactory.newInstance();
SOAPConnection connection =
68
Beispielimplementierungen für Druckdienste
soapConnectionFactory.createConnection();
SOAPFactory soapFactory = SOAPFactory.newInstance();
Als Nächstes erfolgt die Erstellung der SOAP-Message; dazu wird zunächst
ein SOAPMessage-Objekt erzeugt, dessen Struktur der Spezifikation SOAP
1.1 entspricht. Danach werden die einzelnen Teile einer SOAP-Message (SOAPPart, SOAPEnvelope, SOAPHeader und SOAPBody) extrahiert, damit
die SOAP-Message mit Information gefüllt werden kann. Der entsprechende
Code sieht wie folgt aus:
MessageFactory factory = MessageFactory.newInstance();
SOAPMessage message = factory.createMessage();
SOAPPart soapPart = message.getSOAPPart();
SOAPEnvelope envelope = soapPart.getEnvelope();
SOAPHeader header = envelope.getHeader();
SOAPBody body = envelope.getBody();
Nun kann der SOAP-Body mit Information gefüllt werden. Da jedes direkte
Kindelement des SOAP-Bodys einen Namensraum besitzen muss, wird als
erstes das Tag ¡p:Print¿ erstellt, das anschließend als Vaterelement für die
XML-Tags dienen soll, die die Parameter für den Aufruf der Druckfunktion
enthalten. Als Kindelemente von ¡p:Print¿ werden anschließend das Element
¡fileName¿ definiert, das den Namen der zu druckenden Datei speichert, ein
Element ¡noc¿ für die Anzahl der Kopien und ein Element ¡printer¿, das
den Namen des Druckers speichert. Für die letzten beiden Parameter der
Druckfunktion wurden Vorgabewerte implementiert, sie können also, müssen
aber nicht vom Nutzer des Druckdienstes spezifiziert werden.
// add element <p:Print> to the SOAP body
Name bodyName = soapFactory.createName("Print", "p",
"http://www.icsy.de/xml/lawns/");
SOAPBodyElement bodyElement = body.addBodyElement(bodyName);
// add child element <fileName> to the element <p:Print>
Name name1 = soapFactory.createName("fileName");
SOAPElement fileName = bodyElement.addChildElement(name1);
// <fileName>value of the variable file</fileName>
fileName.addTextNode(file);
// add child element <noc> to element <p:Print>
Name name2 = soapFactory.createName("noc");
SOAPElement noc = bodyElement.addChildElement(name2);
// <noc>value of the variable numberOfCopies</noc>
noc.addTextNode(numberOfCopies);
// add child element <printer> to element <p:Print>
Name name3 = soapFactory.createName("printer");
SOAPElement String = bodyElement.addChildElement(name3);
Beispielimplementierungen für Druckdienste
69
// <pinter>value of the variable printerName</printer>
String.addTextNode(printerName);
Nachdem der SOAP-Body gefüllt wurde, kann die zu druckende Datei als
Attachment an die SOAP-Message angefügt werden. Hierzu wird ein DataHandler-Objekt verwendet, das selbstständig den MIME-Type einer Datei
erkennt und in dem Attribut Content-Type speichert. Als Eingabe erhält
das DataHandler-Objekt eine URI, die die Adresse der Datei angibt. Des
Weiteren besitzt der AttachmentPart einer SOAP-Message das Attribut
Content-Id, das alternativ benutzt werden könnte, um den Namen der Datei zu übertragen, anstatt, wie oben angegeben, ein Element im SOAP-Body
dafür anzulegen.
Die resultierende SOAP-Message, die der Client danach mit dem Aufruf
connection.call(message, endpoint) an den Service sendet, sieht wie
folgt aus:
------=_Part_1_7408068.1062688563166
Content-Type: text/xml
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<p:Print xmlns:p="http://www.icsy.de/xml/lawns/">
<fileName>test.xml</fileName>
<noc>1</noc>
<printer>pseudo</printer>
</p:Print>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
------=_Part_1_7408068.1062688563166-Content-Type: text/plain
Content-Id: file
// here is the content of the attached file
------=_Part_1_7408068.1062688563166--
Im obigen Beispiel wurde eine Text-Datei als String an die SOAP-Message
angehängt, deswegen wurde das Content-Type-Attribut des AttachmentParts auf den MIME-Type text/plain“ gesetzt, der Text selbst ist hier aus
”
Platzgründen nicht dargestellt.
Hat die Nachricht den Druckdienst erreicht, so wird die Methode onMessage
(SOAPMessage message) der Klasse PrintService, die das JAXM-Servlet erweitert, aufgerufen. Zunächst werden wie beim Client die Elemente SOAPPart, SOAP-Envelope und SOAP-Body von der SOAP-Message extrahiert,
dann können die Informationen im Body ausgelesen werden. An dieser Stelle
ist es nun erforderlich, dass der Service die Bedeutung der an ihn gesendeten
Daten kennt, und die Daten einsetzt, um die entsprechende Funktion (hier
Druckfunktion) aufzurufen. Da der Client Defaultwerte für den Druckername und die Anzahl an Kopien setzt, wird der Body der Nachricht immer ein
70
Beispielimplementierungen für Druckdienste
¡p:Print¿-Element enthalten, das wiederum drei Kindelemente besitzt. Des
Weiteren muss der Service wissen, in welcher Reihenfolge die Parameter für
die Druckfunktion in den Tags enthalten sind. Mit folgendem Code werden
die Informationen aus dem SOAP-Body ausgelesen und in den entsprechenden Variablen gespeichert:
if (iterator.hasNext()) {
SOAPBodyElement element = (SOAPBodyElement)iterator.next();
// create second iterator to get the children of the first
// body element
Iterator iterator2 = element.getChildElements();
// get first child and use its value to set the variable fileName
if (iterator2.hasNext()) {
SOAPElement child = (SOAPElement)iterator2.next();
fileName = child.getValue();
}
// get second child and use its value to set the variable noc
// then convert the String noc to int
if (iterator2.hasNext()) {
SOAPElement child2 = (SOAPElement)iterator2.next();
noc = child2.getValue();
numberOfCopies = Integer.parseInt(noc);
}
// get the third child and use its value to set the variable printerName
if (iterator2.hasNext()) {
SOAPElement child3 = (SOAPElement)iterator2.next();
printerName = child3.getValue();
}
}
Anschließend werden die Attachments der SOAP-Message ausgelesen. Zuvor
muss allerdings mittels der Abfrage ap.getContentType().equals("text/plain\) getestet werden, welches Format die in der SOAP-Message enthaltene Datei besitzt, damit entschieden werden kann, ob der Service bzw.
Drucker die Datei drucken kann. Besitzt die Datei das richtige Format, so
kann sie unter Hinzunahme der Funktion ap.getContent() in einen String
oder einen ByteArrayInputStream eingelesen werden. Nachdem die Datei
eingelesen wurde, wird sie lokal zwischengespeichert und per UNIX-Befehl
lp“ an den Drucker-Daemon geschickt. Die Ausgabe des Druckbefehls, wird
”
dabei in einen String eingelesen. Zu guter Letzt wird eine Antwort-Nachricht
erstellt, in deren Body der String als Information für den Client enthalten
ist. Ein Beispiel für eine solche zum Kunden gesendete SOAP-Message ist
nachfolgend dargestellt:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
Beispielimplementierungen für Druckdienste
71
<p:Print xmlns:p="http://www.icsy.de/xml/lawns/">
<PrintID>request id is pseudo-73 (1 file(s))</PrintID>
</p:Print>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Der von der Druckfunktion lp ausgegebene String enthält die ID des Druckjobs (im Beispiel entspricht die ID der Zahl 73) und den Namen des Druckers,
auf dem die Datei gedruckt werden soll. Diese Angaben benötigt der Dienstnutzer, falls er den Status erfragen oder den Druckauftrag löschen möchte.
Der Client, der bis zum Erhalt der Nachricht gestoppt wurde, entpackt die
Nachricht und gibt den String für den Dienstnutzer auf der Konsole aus.
Damit der Dienst per Tomcat 3 ins Internet gestellt werden kann, muss noch
eine Datei namens web.xml“ erstellt werden. Sie sieht wie folgt aus:
”
<web-app>
<display-name>Web Service: printService.PrintService</display-name>
<servlet>
<servlet-name>
PrintService
</servlet-name>
<servlet-class>
printService.PrintService
</servlet-class>
<load-on-startup>
1
</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>
PrintService
</servlet-name>
<url-pattern>
/PrintService
</url-pattern>
</servlet-mapping>
</web-app>
Der erste Teil der Datei web.xml“, der von dem Tag <servlet> einge”
rahmt wird, legt fest, dass die Klasse PrintService“ des Pakets printSer”
”
vice“ der Code für das Servlet namens PrintService ist. Der zweite Teil, das
<servlet-mapping>, legt fest, dass das Servlet mit dem Namen PrintSer”
vice“ unter dem relativen Pfad /PrintService“ zu finden ist. Der absolute
”
Pfad bzw. die URL unter der der Druckdienst zu finden ist, ergibt sich aus
der Adresse, unter der die gepackte WAR-Datei zu finden ist, plus dem relativen Pfad. Nun kann die WAR-Datei des PrintServices erstellt werden, die
3
Eine Ablaufumgebung für serverseitiges Java (Servlet) und die Java Server Pages
(JSP) von der Apache Software Foundation.
72
Beispielimplementierungen für Druckdienste
mindestens die Datei web.xml“ und den Code der Klasse PrintService“
”
”
enthalten muss.
Abschließend wird noch die Konfigurationsdatei PrintService.xml“ erstellt,
”
die im Verzeichnis jwsdp-1.2/webapps“ des JWSDP Version 1.2 gespeichert
”
wird und die die erforderlichen Daten enthält, damit beim Start des Tomcat
(Laufzeitumgebung) die WAR-Datei automatisch ins Internet gestellt und
das Servlet des Druckdienstes initialisiert wird. Unter anderem sind in dieser
Datei angegeben, wo die WAR-Datei zu finden ist und über welchen Pfad
sie im Internet erreichbar sein soll. Der Druckdienst dieses Beipiels ist nach
dem Start des Tomcat im Internet unter folgender Adresse zu finden:
http://localhost:8080/PrintService/PrintService.
Der Client wurde nicht als Servlet implementiert, er besitzt eine MainMethode, innerhalb der er eine SOAP-Message erstellt, die zum Aufruf des
Druckdienstes PrintService führt. Ein solcher Client, der keinen MessageProvider benutzt, wird auch als Standalone“-Client bezeichnet. Der kompi”
lierte Code des Client wurde mittels der Datei build.xml“, die das ant-Tool
”
als Eingabe benötigt, in eine WAR-Datei gepackt und kann mit dem Befehl ant run -DfileName=... -Dnumber=... -Dprinter=... aufgerufen
werden. Das Attribut fileName ist Pflicht und muss angegeben werden, für
die anderen beiden Attribute existieren Default-Werte – sie können optional
angegeben werden. Die Reihenfolge der Attribute ist dabei beliebig, denn die
Attribute werden in der Datei build.xml“ über ihren Namen angesprochen
”
und immer in gleicher Reihenfolge an die Main-Methode des Client übergeben. Alternativ wurde im Rahmen dieser Arbeit die gleiche Funktionalität
unter Nutzung der Klasse HTTP-Servlet implementiert. Das HTTP-Servlet
wird hier wegen der großen Ähnlichkeit zum vorhergehenden Beispiel weder
beschrieben noch dargestellt, sie kann im Anhang eingesehen werden.
Abschließende Bemerkungen
6
73
Abschließende Bemerkungen
Die vorliegende Arbeit kann grob in zwei Teile unterteilt werden. Der erste beschäftigt sich zunächst mit der Identifizierung von lokationsbasierten
Diensten und der Kategorisierung gefundener Dienste in einer Taxonomie.
Die erstellte Taxonomie besitzt fünf Hauptkategorien und fünf Hierarchiestufen. Da Verzeichnisse von Web Services zur Zeit vorwiegend von Menschen und nicht von Software-Agenten durchsucht werden (bisher existieren
im besten Fall Ansätze für intelligente Suchagenten), ist es sinnvoll die Anzahl der Hierarchiestufen nicht zu groß zu wählen, damit der Nutzer nicht
zu oft klicken muss, bis er zu seinem Ziel gelangt. Im Bereich der Erstellung intelligenter Suchagenten wird zur Zeit vor allen Dingen an Universitäten geforscht. Die zur Zeit in Entwicklung befindlichen Spezifikationen
(beispielsweise SOAP, UDDI, WSDL, DAML-S) stellen Ansätze dafür dar,
bestimmten XML-Tags, eine eindeutige Semantik zu verleihen, damit die
erstellten Dokumente maschinell bearbeitet werden können.
Nach der Kategorisierung der Dienste wurden ausgewählte Dienste der Taxonomie exemplarisch in WSDL-Fragmenten beschrieben. Bei der Erstellung
der Fragemente wurde auch der Aspekt der Modularität und Wiederverwendung von Beschreibungen betrachtet. Zur Inkludierung bereits vorhandener Fragmente wurde das <import>-Element benutzt. Alternativ könnte
an dieser Stelle bei gleichem Zielnamensraum auch das Element <include>
benutzt oder die seit WSDL Version 1.2 hinzugekommene Möglichkeit der
Vererbung von <interface>-Definitionen herangezogen werden. Durch diese drei Techniken zur Modularisierung von Beschreibungen, kann ein hoher
Grad an Wiederverwendbarkeit von Dienstbeschreibungen erreicht werden.
Im zweiten Teil der Arbeit wurden zwei Dienste exemplarisch mittels des
JWSDP von Sun Microsystems in Java implementiert. Für einen der beiden
Web Services wurde die API JAX-RPC verwendet und der Service mittels zweier verschiedener Ansätze generiert. Beim Top-Down-Ansatz konnten die in der Taxonomie definierten Fragmente zur Generierung von Code
benutzt werden. Allerdings werden noch nicht alle Datentypen bzw. XMLSchema-Definitionen unterstützt, und die WSDL-Datei ist in ihren Möglichkeiten speziell bezüglich der Definition eigener Datentypen noch etwas eingeschränkt. Da die aktuelle Version des JWSDP (1.2) nur die Version 1.1
von WSDL unterstützt, nicht aber die aktuelle Version 1.2, konnte bei der
Modularisierung von WSDL-Dateien von der Möglichkeit der Vererbung des
<interface>-Elements noch kein Gebrauch gemacht werden.
Der zweite Service, der die Druckfunktion anbietet, wurde mit Hilfe der
API JAXM implementiert. Diese API war in der Version 1.1 des JWSDP
noch enthalten, wurde aber in der Version 1.2 ausgelagert. Das JWSDP
besteht aus einer Ansammlung von Technologien, die später in die Plattfor-
74
Abschließende Bemerkungen
men J2EE und J2SE inkludiert werden sollen; das JAXM soll hingegen als
eigenständige Veröffentlichung weiter existieren und wurde deshalb aus dem
Pack ausgelagert. Eines der beiden Pakete des JAXM ist als SAAJ allerdings noch im JWSDP integriert. Beide Schnittstellen, die den Aufbau und
die Handhabung von SOAP-Messages ermöglichen, setzen natürlich voraus,
dass die Semantik ihrer gesendeten Nachrichten im Voraus bekannt ist.
Zusammenfassend gesehen, sind das Thema Web Service sowie die Technologien, die die dahinter stehende Funktionalität realisieren, ein sehr dynamisches Forschungsgebiet, das sich in ständiger Entwicklung befindet. Bis
zur Vision, dass Software-Agenten für Nutzer nach Diensten im Web suchen
und dem Nutzer Möglichkeiten zur Auswahl anbieten, nach Auswahl eines
Dientes die dafür benötigten Komponenten dynamisch koppeln und dafür
sorgen, dass die Aktionen ausgeführt werden, wird noch einige Zeit vergehen.
Das liegt vor allem in der Tatsache begründet, dass bisher nur wenige Dienste
in Verzeichnissen eingetragen und allgemein beschrieben sind. Erst die zunehmende Verbreitung und Nutzung einer Technologie führt dazu, dass die
Technologie sehr wertvoll wird (vergleiche Internet). Aber Web Services haben gute Aussichten, da sie eine relativ breite Unterstützung von der Industrie und Forschung besitzen, auch wenn sie bisher vor allem im B2B-Bereich
benutzt werden. Darüber hinaus werden von den Web Services neben der
Basisfunktionalität viele Zusatzfunktionalitäten gefordert, wie beispielsweise Authentisierung oder Workflow-Unterstützung, für die ebenso Lösungen
bereitgestellt werden müssen. Des Weiteren wird die Vielzahl verschiedener
Kriterien, die bei der Auswahl von Diensten in Verzeichnissen eine Rolle
spielen, zu berücksichtigen sein.
ABBILDUNGSVERZEICHNIS
75
Abbildungsverzeichnis
1
2
3
4
5
6
7
Basis Architektur. Quelle: [CHA02] . . . . . . . . . . . . . . .
SOAP Message. Quelle:[ORMA02] und [NASKSR] . . . . . .
Semantik und WSDL. Quelle: [BOO03] . . . . . . . . . . . . .
Import-Hierarchie . . . . . . . . . . . . . . . . . . . . . . . . .
Use stub“ to make remote call“. Quelle: The JavaTM Web
”
”
Service Developer Pack, Part 2 [ORMA02]. . . . . . . . . . .
Druckdienst Realisierung . . . . . . . . . . . . . . . . . . . . .
Serializers and Deserializers. Quelle: [MAG03], S. 388. . . . .
6
11
15
34
57
60
64
76
LITERATUR
Literatur
[ARM03]
Armstrong, E.; Ball, J.; Bodoff, S.; Carson, D. B.; Fisher, M.;
Fordin, S.; Green, D.; Haase, K.; Jendrock, E.: The Java TM
Web Services Tutorial, 25.07.2003,
http://java.sun.com/webservices/docs/1.2/tutorial/doc/index.html.
[BAR02]
Bartel, M.; Boyer, J.; Fox, B.; LaMaccia, B.; Simon, E.: XMLSingnature Syntax and Processing - W3C Recommendation,
12.02.2002,
http://www.w3.org/TR/2002/REC-xmldsig-core-20020212/.
[BEL02]
Bellwood, T.; Clément, L.; Ehnebuske, D.; Hately, A.; Hondo,
M.; Husband, Y. L.; Januszewski, K.; Lee, S.; McKee, B.;
Munter, J.; von Riegen, C.: UDDI Version 3.0 – UDDI Spec
Technical Committee Specification, 19.07.2002,
http://uddi.org/pubs/uddi v3.htm.
[BOO03]
Booth, D.; Le Hégaret, P.; Liu, C. K.: Web Services Description
Language (WSDL) Version 1.2 Part 0: Primer, Editors copy,
01.06.2003,
http://www.w3.org/2002/ws/desc/wsdl12-primer.
[BRA00]
Bray, T.; Paoli, J; Sperberg-McQueen, C. M.; Maler, E.:
Extensible Markup Language (XML) 1.0 (Second Edition) –
W3C Recommendation 06.10.2000,
http://www.w3.org/TR/2000/REC-xml-20001006.
[CHA02]
Champion, M.; Ferris, C.; Newcomer, E.; Orchard, D.: Web
Service Architecture - W3C Working Draft, 14.11.02,
http://www.w3.org/TR/2002/WD-ws-arch-20021114/.
[CHJE03] Chappell, D.; Jewell, T.: Java Web Services, (Kapitel 7 verwendet) O’ Reilly & Associates, Inc., Sebastotpol (USA), März 2003.
[CHI03]
Chinnici, R.; Gudgin, M.; Moreau, J-J.; Weerawarana, S.: Web
Services Description Language (WSDL) Version 1.2 - W3C
Working Draft 11.06.03,
LITERATUR
77
http://www.w3.org/TR/2003/WD-wsdl12-20030611.
[CHR01]
Christensen, E.; Curbera, F.; Meredith, G.; Weerawarana, S.:
Web Services Description Language (WSDL) Version 1.1 W3C Working Draft 15.03.2001,
http://www.w3.org/TR/2001/NOTE-wsdl-20010315.
[COY02]
Coyle, F. P.: XML, Web Services, and the Data Revolution.
Addison-Wesley by Pearson Education , Inc. Boston 2002.
[FAL01]
Fallside, D. C.: XML Schema Part 0: Primer - W3C Recommendation, 02.05.2001,
http://www.w3.org/TR/2001/REC-xmlschema-0-20010502/.
[FRA99]
Franks, J.; Hallam-Baker, P.; Hostetler, J.; Lawrence, S.; Leach,
P.; Luotonen, A.; Stuart, L.: HTTP Authentication: Basic and
Digest Access Authentication, RFC 2617, Internet Engineering
Task Force, June 1999,
ftp://ftp.isi.edu/in-notes/rfc2617.txt.
[GRA01]
Granada Research: Using the UNSPSC – United Nations Standard Products and Services Code, White Paper, Why Coding
and Classifying Products is Critical to Success in Electronic
Commerce, October 2001,
http://www.unspsc.org/AdminFolder/Documents/UNSPSC White Paper.doc.
[IMA02]
Imamura, T.; Dillaway, W.; Simon, E.: XML Encrytion Syntax
and Processing, W3C Recommendation 10.12.2002,
http://www.w3.org/TR/2002/REC-xmlenc-core-20021210/.
[Kre02]
Kreidel, M.; Kemper, A.; Kossmann, D.; Kreutz, A.: Web
Services, in: Erhard Rahm, Gottfried Vossen (Hrsg.), Web
& Datenbanken. Konzepte, Architekturen, Anwendungen,
Dpunkt-Verlag, Heidelberg, 2002, S. 293 - 331.
[KUWÖ]
Kuschke, M.; Wölfel, L.: Web Services - Kompakt. Spektrum
Akad. Verlag, Heidelberg, Berlin 2002.
78
LITERATUR
[MAG03]
McGovern, J.; Stevens, E. M.; Stevens, M.; Tyagi, S.; Mathew,
S.: Java Web Service Architecture, Elsevier Science, April 2003.
[MOSC]
Moreau, J-J.; Schlimmer, J.: Web Service Description Language
(WSDL) Version 1.2 Part 3: Bindings - W3C Working Draft
11.06.03,
http://www.w3.org/TR/2003/WD-wsdl12-20030611.
[NASKSR] Nagappan, R.; Skoczylas, R.; Sriganesh, R. P.: Developing
Java Web Services - Architecting and Developing Secure Web
Services Using Java. Wiley Publishing Inc., Indianapolis,
Indiana, 2003.
[ORMA02] Orth, E.; Mandava, R.: The JavaTM Web Services Developer
Pack, Part 2, Oktober 2002,
http://developer.java.sun.com/developer/technicalArticles/WebServices/WSPack2/.
79
Taxonomie
A
Taxonomie
Output Services:
1. Print Services
1.1 Black-White Print Services
1.1.1 Print Ascii Files
1.1.1.1 Print PS
1.1.1.2 Print HPGL
1.1.2 Print Binary Files
1.1.2.1 Print GIF
1.1.2.2 Print JPEG
1.1.2.3 Print PCL
1.1.2.4 Print PDF
1.1.2.5 ...
1.1.2.6 Print PNG
1.2 Color Print Services
1.2.1 Print Ascii Color
1.2.1.1 Print PS
1.2.1.2 Print HPGL
1.2.2 Print Binary Color
1.2.2.1 Print GIF
1.2.2.2 Print PCL
1.2.2.3 Print PDF
1.2.2.4 ...
1.2.2.5 Print PNG
2. Play
2.1 Play Audio
2.1.1 Play MP3
2.1.2 Play WAV
2.1.3 ...
2.2 Play Video
2.2.1
2.2.2
2.2.3
2.2.4
2.2.5
Play
Play
Play
...
Play
MPEG1
MPEG2
MPEG4
Quicktime
80
Taxonomie
3. Display
3.1 Display Document
3.1.1 Display ASCII Document
3.1.1.1 Display PS
3.1.1.2 Display HPGL
3.1.1.3 Display TXT
3.1.1.4 ...
3.1.2 Display Binary Document
3.1.2.1 Display DOC
3.1.2.2 Display PCL
3.1.2.3 Display PPT
3.1.2.4 ...
3.2 Display Image
3.2.1
3.2.2
3.2.3
3.2.4
Display GIF
Display JPEG
Display BMP
...
Input Services:
1. Scan
2. Record
2.1 Audio Input
2.2 Video Input
3. Sensor Input
3.1 Measure Temperature
3.2 Measure Ozon
3.3 ...
3.4 DVD Input
3.5 Keyboard Input
3.6 Mouse Input
Storage and Computational Services
1. Save on external data mediums
1.1 Burn CD
1.2 Burn DVD
Taxonomie
2. Computational Services
Device Control
1. Get-functions
2. Set-functions
Communication Services
1. Chat
2. Message Services (Nachrichtendienste)
2.1 Fax
2.2 Mail
2.3 SMS
3. Conferences
3.1 Telephone Conference (over IP)
3.1.1 Dial In
3.1.2 Dial Out
3.2 Video Conference
3.2.1 Dial In
3.2.2 Dial Out
81
82
B
selbstdefinierte WSDL für den Druckdienst
selbstdefinierte WSDL für den Druckdienst
<?xml version="1.0" encoding="UTF-8"?>
<definitions
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:tns="http://com.test/wsdl/Print"
xmlns:ns2="http://com.test/types/Print"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
name="Print" targetNamespace="http://com.test/wsdl/Print">
<types>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:tns="http://com.test/types/Print"
xmlns:soap11-enc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
targetNamespace="http://com.test/types/Print">
<import namespace="http://schemas.xmlsoap.org/soap/encoding/"/>
<simpleType name="StatusType">
<restriction base="string">
<enumeration value="queued"/>
<enumeration value="printing"/>
<enumeration value="printed"/>
</restriction>
</simpleType>
<complexType name="ArrayOfPrinterQueueEntry">
<complexContent>
<restriction base="soap11-enc:Array">
<attribute ref="soap11-enc:arrayType"
wsdl:arrayType="tns:PrinterQueueEntry[]"/>
</restriction>
</complexContent>
</complexType>
<complexType name="PrinterQueueEntry">
<sequence>
<element name="fileName" type="string"/>
<element name="percentagePrinted" type="int"/>
<element name="positionInPrinterQueue" type="int"/>
<element name="printID" type="int"/>
<element name="status" type="string"/>
</sequence>
</complexType>
</schema>
</types>
<message name="remove">
<part name="printID" type="xsd:int"/>
<part name="printerName" type="xsd:string"/>
</message>
<message name="removeResponse">
<part name="printacknowledgement" type="xsd:string"/>
</message>
<message name="statusOfJob">
<part name="printID" type="xsd:int"/>
<part name="printerName" type="xsd:string"/>
selbstdefinierte WSDL für den Druckdienst
83
</message>
<message name="statusOfJobResponse">
<part name="status" type="ns2:StatusType"/>
</message>
<message name="viewPrinterQueue">
<part name="printerName" type="xsd:string"/>
</message>
<message name="viewPrinterQueueResponse">
<part name="queue" type="ns2:ArrayOfPrinterQueueEntry"/>
</message>
<portType name="Print">
<operation name="remove" parameterOrder="printID printerName">
<input message="tns:remove"/>
<output message="tns:removeResponse"/>
</operation>
<operation name="statusOfJob" parameterOrder="printID printerName">
<input message="tns:statusOfJob"/>
<output message="tns:statusOfJobResponse"/>
</operation>
<operation name="viewPrinterQueue" >
<input message="tns:viewPrinterQueue"/>
<output message="tns:viewPrinterQueueResponse"/>
</operation>
</portType>
<binding name="PrintIFBinding" type="tns:Print">
<operation name="remove">
<input>
<soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
use="encoded" namespace="http://com.test/wsdl/Print"/>
</input>
<output>
<soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
use="encoded" namespace="http://com.test/wsdl/Print"/>
</output>
<soap:operation soapAction=""/>
</operation>
<operation name="statusOfJob">
<input>
<soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
use="encoded" namespace="http://com.test/wsdl/Print"/>
</input>
<output>
<soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
use="encoded" namespace="http://com.test/wsdl/Print"/>
</output>
<soap:operation soapAction=""/>
</operation>
<operation name="viewPrinterQueue">
<input>
<soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
use="encoded" namespace="http://com.test/wsdl/Print"/>
</input>
<output>
<soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
84
selbstdefinierte WSDL für den Druckdienst
use="encoded" namespace="http://com.test/wsdl/Print"/>
</output>
<soap:operation soapAction=""/>
</operation>
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="rpc"/>
</binding>
<service name="Print">
<port name="PrintIFPort" binding="tns:PrintIFBinding">
<soap:address xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
location="http://localhost:8080/Print-jaxrpc/Print"/>
</port>
</service>
</definitions>
PrintService – HTTP-Servlet
C
85
PrintService – HTTP-Servlet
C.1
Client-Code
package printOrder;
import
import
import
import
import
import
import
java.net.*;
java.io.*;
javax.xml.soap.*;
java.util.*;
javax.servlet.*;
javax.servlet.http.*;
javax.activation.*;
import org.apache.commons.logging.*;
public class PrintOrder extends HttpServlet {
static Log logger = LogFactory.getFactory().getInstance("PrintServiceHttp");
String to = null;
String data = null;
ServletContext servletContext;
// Connection to send message
private SOAPConnection con;
public void init(ServletConfig servletConfig) throws ServletException {
super.init(servletConfig);
servletContext = servletConfig.getServletContext();
try {
// create a SOAP point-to-point connection
SOAPConnectionFactory soapConnectionFactory =
SOAPConnectionFactory.newInstance();
con = soapConnectionFactory.createConnection();
} catch (Exception e) {
logger.error("Unable to open a SOAPConnection", e);
}
}
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException {
// create, send and receive message (same as JAXM-Servlet)
}
}
C.2
Service-Code
package printService;
import javax.xml.soap.*;
import java.util.*;
import java.io.*;
86
Service-Code
import
import
import
import
javax.servlet.*;
javax.xml.*;
javax.servlet.http.*;
javax.xml.transform.*;
public class PrintService extends HttpServlet {
static MessageFactory factory = null;
/*static {
try {
factory = MessageFactory.newInstance();
System.out.println("Hier bin ich!");
} catch (Exception e) {
e.printStackTrace();
}
}*/
public void init(ServletConfig servletConfig) throws ServletException {
super.init(servletConfig);
try {
factory = MessageFactory.newInstance();
System.out.println("Hier bin ich!");
} catch (Exception e) {
throw new ServletException("Unable to create message factory"
+ e.getMessage());
}
}
public void doPost (HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
try {
// get all the headers from the HTTP request
MimeHeaders headers = getHeaders(req);
// get the body of the HTTP request
InputStream is = req.getInputStream();
//Now internalize the contents of a HTTP request and create a SOAPMessage
SOAPMessage message = factory.createMessage(headers, is);
SOAPMessage reply = null;
reply = onMessage(message);
if (reply != null) {
if (reply.saveRequired()) {
reply.saveChanges();
}
resp.setStatus(HttpServletResponse.SC_OK);
putHeaders(reply.getMimeHeaders(), resp);
Service-Code
87
// write out the message on the response stream
OutputStream os = resp.getOutputStream();
reply.writeTo(os);
os.flush();
} else
resp.setStatus(HttpServletResponse.SC_NO_CONTENT);
} catch (Exception e) {
throw new ServletException("POST failed " + e.getMessage());
}
}
static MimeHeaders getHeaders(HttpServletRequest req) {
Enumeration enum = req.getHeaderNames();
MimeHeaders headers = new MimeHeaders();
while (enum.hasMoreElements()) {
String headerName = (String)enum.nextElement();
String headerValue = req.getHeader(headerName);
StringTokenizer values = new StringTokenizer(headerValue, ",");
while (values.hasMoreTokens())
headers.addHeader(headerName, values.nextToken().trim());
}
return headers;
}
static void putHeaders(MimeHeaders headers, HttpServletResponse res) {
Iterator it = headers.getAllHeaders();
while (it.hasNext()) {
MimeHeader header = (MimeHeader)it.next();
String[] values = headers.getHeader(header.getName());
if (values.length == 1)
res.setHeader(header.getName(), header.getValue());
else {
StringBuffer concat = new StringBuffer();
int i = 0;
while (i < values.length) {
if (i != 0)
concat.append(’,’);
concat.append(values[i++]);
}
res.setHeader(header.getName(),
concat.toString());
}
}
}
88
Service-Code
public SOAPMessage onMessage (SOAPMessage message) {
// handling of the received message (same as JAXM-Servlet)
}
}
Herunterladen