Mit Perl einen Webservice abzufragen, kann eigentlich nicht so schwer sein, dachte ich. Allerdings habe ich dann, als ich mir SOAP::Lite und dessen Dokumentation ansah, schien das Unterfangen schon deutlich komplizierter. So großartig dieses Modul sein mag, die Dokumentation war für meinen Geschmack zu verstreut und ich hätte mir einige Code-Beispiele gewünscht. Vermutlich lag es aber auch nur daran, dass meine Programmierkenntnisse doch sehr beschränkt sind. Nach einigem Hin und her hat es schließlich dann doch noch geklappt. Im Folgenden zeige ich zwei alternative Möglichkeiten, die zwar beide lauffähig, aber vielleicht nicht gerade effizient sind.
Mein erster Versuch war dann zwar funktionstüchtig, aber so weit davon entfernt elegant zu sein, dass ich nicht ganz zufrieden damit sein konnte. Das Programm verbindet sich mit einem Webservice. Dieser Service verlangt eine Authentifizierung via Klartext- oder MD5-Passwort. Die Funktion GetServerVersion() bildet hier eine Ausnahme und wird zu Testzwecken aufgerufen.
| # | Code |
|---|---|
| 0001 | #!/opt/local/bin/perl -w |
| 0002 | use SOAP::Lite;# alternatively ( +trace => all, maptype => {} ); |
| 0003 | use strict; |
| 0004 | |
| 0005 | # configure server uri |
| 0006 | my $service_url = 'http://127.0.0.1:8110/config'; |
| 0007 | my $cfg_user = 'stephan.hochhaus'; |
| 0008 | my $cfg_password = 'password'; |
| 0009 | |
| 0010 | # test server connection by using a method w/o the need for authentication |
| 0011 | print "Testing the connection by requesting the method GetServerVersion().\nResult: "; |
| 0012 | print &send_request("GetServerVersion"); |
| 0013 | |
| 0014 | # initialize with login credentials |
| 0015 | my $username = SOAP::Data->type('string'); |
| 0016 | $username->name('Username'); |
| 0017 | $username->value($cfg_user); |
| 0018 | my $password = SOAP::Data->type('string'); |
| 0019 | $password->name('Password'); |
| 0020 | $password->value($cfg_password); |
| 0021 | |
| 0022 | # get SessionID - required for most methods |
| 0023 | my $sessionID = SOAP::Data->type('string'); |
| 0024 | $sessionID->name('SessionID'); |
| 0025 | $sessionID->value(&send_request("Login",$username,$password)); |
| 0026 | |
| 0027 | # getList() on ObjectName |
| 0028 | my $DateTimeNow = SOAP::Data->type('dateTime'); |
| 0029 | $DateTimeNow->name('Now'); |
| 0030 | $DateTimeNow->value(&create_timestamp()); |
| 0031 | my $ByName = SOAP::Data->type('string'); |
| 0032 | $ByName->name('ByName'); |
| 0033 | $ByName->value('ObjectName'); |
| 0034 | print &send_request("GetList",$sessionID,$DateTimeNow,$ByName); |
| 0035 | |
| 0036 | # be nice, shut the door behind you! |
| 0037 | print &send_request("Logout",$sessionID); |
| 0038 | |
| 0039 | # perfom method calls to the webservice |
| 0040 | sub send_request{ |
| 0041 | my $method = shift @_; |
| 0042 | my $client = SOAP::Lite |
| 0043 | ->on_action( sub { return $method;}) ->uri('') |
| 0044 | ->proxy($service_url); |
| 0045 | my $result = $client->$method(@_); |
| 0046 | unless ($result->fault) { |
| 0047 | return $result->result(); |
| 0048 | } |
| 0049 | else { |
| 0050 | print join ', ', $result->faultcode, $result->faultstring, $result->faultdetail; |
| 0051 | } |
| 0052 | } |
| 0053 | |
| 0054 | # returns current timestamp |
| 0055 | sub create_timestamp { |
| 0056 | my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime(time); |
| 0057 | return sprintf "%4d-%02d-%02dT%02d:%02d:%02d",$year+1900,$mon+1,$mday,$hour,$min,$sec; |
| 0058 | } |
Was genau treibt der Code? Insgesamt werden anhand der Funktion send_request drei Funktionen des Webservice aufgerufen:
- GetServerVersion()
- Login(Username,Passwort) (alternativ auch als LoginMD5 implementiert)
- GetList(SessionID,Timestamp,ObjectName)
- Logout(SessionID)
Da der .Net-Webserver seine WSDL-Datei auf Verlangen anzeigt, geht die Abfrage des Services sogar auch noch deutlich einfacher:
| # | Code |
|---|---|
| 0001 | #!/opt/local/bin/perl -w |
| 0002 | use SOAP::Lite;# add ' +trace' for verbose output |
| 0003 | use strict; |
| 0004 | |
| 0005 | # configure server uri |
| 0006 | my $service_url = 'http://127.0.0.1:8110/config'; |
| 0007 | my $cfg_user = 'stephan.hochhaus'; |
| 0008 | my $cfg_password = 'password'; |
| 0009 | |
| 0010 | # stress test! |
| 0011 | for (my $i = 0; $i<100; $i++){ |
| 0012 | &call_method_args(); |
| 0013 | } |
| 0014 | |
| 0015 | # returns current timestamp |
| 0016 | sub create_timestamp { |
| 0017 | my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime(time); |
| 0018 | return sprintf "%4d-%02d-%02dT%02d:%02d:%02d",$year+1900,$mon+1,$mday,$hour,$min,$sec; |
| 0019 | } |
| 0020 | |
| 0021 | # calls methods |
| 0022 | sub call_method_args { |
| 0023 | my $service = SOAP::Lite |
| 0024 | -> service($service_url . '?wsdl'); |
| 0025 | my $sessionID = $service->LoginMD5($cfg_user, $cfg_password); |
| 0026 | my $result = $service->Get($sessionID,&create_timestamp,'ObjectName',0,0); |
| 0027 | $service->Logout($sessionID); |
| 0028 | } |
Links:
- Quick Start Guide with SOAP and SOAP::Lite – Dokumentation von SOAP
- consume a .NET web service with Perl – Make a client, for a .NET web service, with Perl and SOAP::Lite
- SOAP Client – Kostenloser Webservice-Client für Mac OS X
- WebServiceStudio 2.0 – Kostenloser Webservice-Client für Windows

Keine Kommentare
Keine Kommentare→