简体   繁体   中英

Perl SOAP Web Service Call With XML

I am calling SOAP web services by using Perl with the SOAP::Lite module as follows:

my $soap = SOAP::Lite->on_action( sub { join '/', @_ } )
        ->readable( 1 )
        ->uri( $uri )
        ->proxy( $proxy )
        ->ns( $ns );

$soap->call(
        'method' => ( SOAP::Data->name( ... ) )
);

Is there any way of calling customer web service by using XML definition displayed at SOAPUI instead of writing SOAP::Data etc? It would be easier if there is an option to do this.

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:int="xxx">
  <soapenv:Header/>
  <soapenv:Body>
    <int:method>
      <!--Optional:-->
      <int:userName>?</int:userName>
      <!--Optional:-->
      <int:password>?</int:password>
      <!--Optional:-->
      ...
    </int:method>
  </soapenv:Body>
</soapenv:Envelope>

For example, is something below possible?

    my $xml_string = qq((<soapenv:Envelope 
    xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
    xmlns:int="xxx">
       <soapenv:Header/>
       <soapenv:Body>
          <int:method>
             <!--Optional:-->
             <int:userName>$username</int:userName>
             <!--Optional:-->
             <int:password>$password</int:password>
             <!--Optional:-->
           ............
           ...........   
           </int:method>
       </soapenv:Body>
    </soapenv:Envelope>
));
$xml_string->process;

You can use the heredoc style and submit your whole soap data as normal post request.

You can also then make use of the non-blocking style in case the SOAP response from the remote host takes too long and you have to run other code in meanwhile.

The designers of the SOAP protocol are not happy about this simplified use, because it's too simple.

use strict;
use warnings;
use Mojo::UserAgent;
my $ua = Mojo::UserAgent->new;

my $username = "MyUsername";
my $password = "MyPassword";

my $hash;
$hash->{variable} = "SomeText";

my $SOAP_request = <<"END_MESSAGE";
<soapenv:Envelope 
    xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
    xmlns:int="xxx">
       <soapenv:Header/>
       <soapenv:Body>
          <int:method>
             <!--Optional:-->
             <int:userName>$username</int:userName>
             <!--Optional:-->
             <int:password>$password</int:password>
             <!--Optional:-->
             <int:variable>@{[$hash->{variable}]}
           ............
           ...........   
           </int:method>
       </soapenv:Body>
</soapenv:Envelope>
END_MESSAGE

Blocking

my $res = $ua->post('http:///www.example.com' => $SOAP_request);
print $res->body;

Non-Blocking

$ua->post('http://www.example.com' => $SOAP_request => sub { 
   my ($c, $tx) = @_; 
   print $tx->res->body;              
});

Reading the response

use SOAP::Lite;
my $som = SOAP::Deserializer->deserialize($tx->res->text);

# Simple xPath navigation through tags
$som->valueof('//Response//SomeInformation//Details');

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM