gSOAP

Ich hatte gestern erst über gSOAP und Qt gesprochen, jetzt wollte ich nochmal kurz was zu gSOAP selber sagen.

gSOAP gibt einem die Möglichkeit ein fertige Soap-Client für c++ zu erstellen. Die einzige Voraussetzung dafür ist ein bereits fertiges WSDL-File, was den Webservice beschreibt. Ich benutze gSOAP gerade in der Uni, um ein Webservice anzusprechen, der mit Hilfe von Java erstellt wurde und habe da noch keine Probleme gefunden.

Dann hier eine kurze Erklärung, wie man das macht:

1. Installation von gSAOP

im Ubuntu Repository findet man bereits gSOAP, d.h. ein kleines apt-get install gsoap reicht. Unter 12.04 ist das die Version 2.8.4, aktuell ist 2.8.11. Wenn man die aktuellste Version braucht/will, muss man sich das selber kompilieren.

2. Erstellen des SOAP-Client

Dann braucht man Zugriff auf eine fertige WSDL-Datei. Die kann irgendwo im Netz liegen oder auch lokal vorhanden sein.
Mit diesem Code erzeugt gSOAP ein Header File name wsdl-header.h, was es zum erstellen des Clients braucht. Ich gehe davon aus, dass wir dafür ein extra Ordner anlegen.

mkdir gsoap
cd gsoap
wsdl2h -o wsdl-header.h http://127.0.0.1:8888/webservice?WSDL

Dann erstellen wir uns den eigentlich Client:

soapcpp2 -C wsdl-header.h -I/usr/share/gsoap/import

Den Import Pfad muss man anpassen, sollten gSOAP selber kompiliert sein.
wsdl2h und soapcpp2 sind die beiden gSOAP-Tools, die uns die ganze Arbeit abnehmen.

Dann lösen wir noch eine Abhängigkeit auf. Hier muss ggf. auch der Pfad angepasst werden.

cp /usr/share/gsoap/import/stlvector.h ./

Wenn man sich jetzt das Header-File wsdl-header.h anschaut, findet man die notwendige Funktionsnamen und zu verwendenden Attribute.
Aus der Webservice-Funktion „login“ wird dann z.B. „__ns1__login“.

In seinem C++ Code lässt sich das jetzt alles einbinden und verwenden:

#include "gsoap/soapH.h"
#include "gsoap/<webservice-namespace>.nsmap"

Beim Erstellen des Clients werden verschiedene Dateien angelegt, eine davon endet auf .nsmap. Diese muss auch eingebunden werden, deren Namen ist aber vom Namespace des Webservices im WSDL-File abhängig.

Ein SOAP Aufruf kann dann wie folgt aussehen, wobei der mittlere Teil start von eurem Webserver abhängig ist.

//überall gleich
struct soap soap;
soap_init(&soap);


ns1__login *login = new ns1__login();
ns1__loginResponse *loginResponse = new ns1__loginResponse();
string a1 = this->username.toUtf8().constData();
string a2 = this->password.toUtf8().constData();
//Parameter user
login->arg0 = &a1;
//Parameter pass
login->arg1 = &a2;
const char *soap_url = this->getWebserviceUrl().toUtf8().constData();
if(soap_call___ns1__login(&soap, soap_url, NULL, login, loginResponse) == SOAP_OK) {
                sessionid  = QString::fromStdString(*(loginResponse->return_));
}

//überall gleich
soap_destroy(&soap);
soap_end(&soap);
soap_done(&soap);

Anmerkung:
Ich überschreibe hier auch die im WSDL-File hinterlegte URL des Webservice. Möchte man das nicht, übergibt man statt soap_url einfach NULL.
Möchte man HTTPS verwenden, muss man beim Kompilieren die openssl Library mit einbinden.

Hinterlasse eine Antwort

Deine Email-Adresse wird niemals veröffentlicht. Pflichtfelder sind mit * gekennzeichnet.