|
APEX und Webservices: Arbeiten mit APEX_WEB_SERVICE
| Erscheinungsmonat |
APEX-Version |
Datenbankversion |
| August 2011 |
ab 4.0 |
ab 10.2 |
Web Services verbreiten sich mehr und mehr
in den IT-Landschaften; sie sind
das zentrale Element service-orientierter Architekturen (SOA).
Kern dieser
Architektur ist es, bestimmte, häufig benötigte Funktionalität als Web Service
bereitzustellen, so dass verschiedenste Applikationen darauf zugreifen können,
und zwar unabhängig von der verwendeten Technologie.
Application Express bietet bereits seit den ersten Versionen eine sehr gute
Unterstützung für Web Services an. Nutzer einer Standard- oder
Enterprise Edition der Datenbank finden in
diesem Community-Tipp eine Anleitung zur automatischen Einrichtung
eines PL/SQL-Pakets für einen Webservice - die Methoden des Web Service werden dann als
Prozeduren bzw. Funktionen des Package eingerichtet. Alles geht vollautomatisch - benötigt wird
lediglich die URL zur Webservice-Schnittstellenbeschreibung (WSDL).
Allerdings basiert der beschriebene Weg auf der datenbankinternen Java-Engine und
ist damit auf einer OracleXE-Datenbank nicht lauffähig. Für diese Anwender,für solche,
die nicht mit der Datenbankinternen JVM arbeiten oder für diejenigen, die den Webservice-Aufruf
genau kontrollieren möchten, gibt es seit APEX 4.0 das
PL/SQL-Paket APEX_WEB_SERVICE. Im Vergleich zu der
auf Java basierenden Variante, die das PL/SQL-Paket vollautomatisch
erstellt, muss man hier als Entwickler aber wesentlich mehr selbst machen. Wie es im Detail geht,
wird anhand eines praktischen Beispiels erläutert.
Vorbereitungen
Zunächst müssen in der Datenbank die Voraussetzungen für eine Kommunikation
mit dem Web Service geschaffen werden.
-
In einer 11g-Datenbank muss das APEX Parsing Schema die nötigen Privilegien in
Form einer Netzwerk-ACL erhalten - wie das geht, ist
in diesem Community-Tipp
beschrieben.
-
Wenn sich Ihre Datenbank hinter einer Firewall befindet, muss der Proxy-Server
in den Attributen der APEX-Applikation eingestellt werden. Alternativ kann
auch die PL/SQL-Prozedur UTL_HTTP.SET_PROXY verwendet werden.
Webservice-Schnittstelle betrachten
Zum Programmieren mit dem Paket APEX_WEB_SERVICE muss man sich ein wenig mit
der Schnittstelle des Web Service auseinandersetzen - als Beispiel wollen wir in
diesem Community-Tipp mit dem frei zugänglichen Web Service
Global Weather arbeiten.
Webservice "Global Weather"
Wie zu jedem Webservice ist
auch hierfür eine
Schnittstellenbeschreibung als WSDL-Dokument verfügbar. Leider
sind diese auf XML basierenden Dokumente nur sehr schwer lesbar. Man hilft sich am
besten mit einem Werkzeug - und hier ist die freie Software
soapUI
empfehlenswert (Abbildung 1).
Abbildung 1: Webservice-Werkzeug "soapUI"
Navigueren Sie im Menü File zu den Preferences und stellen Sie den Proxy-Server
ein, wenn Sie sich hinter einer Firewall befinden. Erzeugen Sie dann ein
neues Projekt, geben Sie, wie in Abbildung 1 dargestellt, die URL zum WSDL-Dokument
(http://www.webservicex.com/globalweather.asmx?WSDL)
als Initial WSDL/WADL ein und klicken Sie auf OK. Das Werkzeug wird das WSDL-Dokument
dann laden und die Information für Sie aufbereiten. Wenn Sie Baum links den Eintrag
getWeather aufklappen und Request 1 doppelklicken, erscheint auf der rechten
Hälfte eine Vorlage für einen SOAP-Request zum Abholen der Wetterdaten (genau dieses
XML werden Sie später bei der Arbeit mit APEX_WEB_SERVICE noch brauchen).
Abbildung 2: Webservice "GlobalWeather" in soapUI
Tragen Sie nun in etwas in die Vorlage ein; nehmen Sie bspw. wie in Abbildung 3
dargestellt, Munich als CityName und Germany als CountryName. Klicken Sie dann
auf den kleinen grünen Pfeil links oben - soapUI wird Ihren Request dann an
den Server senden und die Antwort auf der rechten Seite darstellen.
Abbildung 3: Test des Webservice "GlobalWeather" mit soapUI"
Man sieht, dass die Angaben eines Webservice-Requests in ein XML-Dokument
"gepackt" werden müssen - dieses besteht aus einem SOAP-Envelope , welcher wiederum
einen Header und einen Body hat. Dies ist für alle SOAP-Requests gleich.
Die Angaben innerhalb des Body sind bei jedem Webservice anders und richten sich
nach den Angaben im WSDL.
Die Antwort ist ebenfalls in einen Envelope verpackt, der wiederum Header und
Body enthält. Auch für die Webservice-Antwort gilt, dass die Struktur innerhalb
innerhalb des "Body" vom Webservice selbst abhängt - GlobalWeather liefert eine XML-Unterstuktur
zurück; die Experten merken aber sofort, dass es eine sog. CDATA-Section ist; es ist also quasi "ein XML-Dokument in einem XML-Dokument". Zum Verarbeiten der XML-Antwort bietet die Datenbank alle nötigen Funktionen an - SQL-Funktionen wie EXTRACTVALUE oder EXTRACT erlauben das Extrahieren der gewünschten Informationen aus dem XML-Dokument.
Mit diesen Informationen können wir im nächsten Schritt also mit dem PL/SQL-Paket
APEX_WEB_SERVICE arbeiten.
Arbeiten mit APEX_WEB_SERVICE
Als generelle Vorgehensweise empfiehlt sich sicherlich, das Paket APEX_WEB_SERVICE
nicht direkt in der APEX-Applikation zu nutzen, sondern ein eigenes PL/SQL-Paket
für den Web-Service zu schreiben - in diesem wird APEX_WEB_SERVICE dann verwendet. Die
APEX-Anwendung arbeitet jedoch mit dem Wrapper-Paket. Für den Webservice GlobalWeather
könnte das PL/SQL-Paket dann wie folgt aussehen ...
Die Package-Spezifikation entspricht nun recht genau der Webservice-Beschreibung;
Mit Hilfe von APEX_WEB_SERVICE werden wir es nun implementieren. Die eigentliche
Arbeit wird dabei von APEX_WEB_SERVICE.MAKE_REQUEST erledigt.
Hier erkennen Sie vielleicht den Parameter P_ENVELOPE wieder - hier wird
das XML-Dokument, welches Sie im soapUI als Request erstellt und bearbeitet haben,
übergeben. Die Antwort, die als SOAP-Envelope (Abbildung 3 rechts) gesendet wird,
wird von MAKE_REQUEST als XMLTYPE zurückgegeben. APEX_WEB_SERVICE.PARSE_XML erlaubt
dann das Zerlegen der Struktur - die Wetterinformationen werden also aus dem SOAP-Envelope
extrahiert (in diesem Fall ergibt sich allerdings wiederum ein XML-Dokument). Die
Nutzung des WebService in einem einfachen anonymen PL/SQL-Block könnte also so aussehen ..
Allerdings passt dies nicht zu der Package-Spezifikation, die wir weiter oben
schon festgelegt haben. Basierend auf dem anonymen Block lässt sich das Package
aber nun recht schnell implementieren
(Skript-Download). Der folgende Code implementiert auch
die Methode getCitiesByCountry des Webservice. Hier
wird die XML-Antwort des Webservice auch schon direkt in ein PL/SQL Array übernommen.
Den Web Service wie ein PL/SQL-Paket nutzen
Das fertige PL/SQL-Paket sieht nach dem Einspielen wie folgt aus:
Die beiden Funktionen können nun wie normale PL/SQL-Funktionen verwendet werden;
die Implementierung als eigenes Package ist zwar ein wenig Arbeit, lohnt sich
aber bereits bei der zweiten Nutzung des Web-Service. Gerade bei der Art und Weise,
wie das PL/SQL-Package erstellt wird, unterscheidet sich die hier beschrieben Arbeit mit APEX_WEB_SERVICE
von der
Variante basierend auf der datenbankinternen Java VM. Bei letzterer
macht das jpub-Werkzeug die ganze Arbeit - mit SOAP-Envelopes muss man sich dort nicht
herumschlagen. Im Gegenzug hat man bei der Variante mit APEX_WEB_SERVICE mehr Kontrolle
über das Package - denn man baut es eben selbst. Die "richtige"
hängt von den konkreten Anforderungen ab. Die Nutzung des Pakets erfolgt, wie schon gesagt, wie
mit jedem anderen PL/SQL-Paket und funktioniert
genauso wie bei der Variante basierend auf der datenbankinternen Java VM - dort beschrieben
im Abschnitt Den Web Service wie ein PL/SQL-Paket nutzen.
Hier einige Beispiele - zunächst werden alle "Cities" in Deutschland abgerufen:
Als nächstes wird das Wetter am Flughafen Hamburg abgerufen ...
Zurück zur Community-Seite
|