Chapter 3. Make a SOAP client with Perl and SOAP::Lite

Table of Contents
3.1. Interoperability demo: consume my JWSDP RCX web service with Perl/cgi and SOAP::Lite.
3.1.1. Consume a simple remote procedure
3.1.2. Consume a remote procedure returning arrays with SOAP::Lite
3.2. Interoperability demo: consume a .NET web service with Perl.
3.3. Perl XML HTTP Post to a web service.
3.3.1. Post a SOAP message to my Java WSDP web service.
3.3.2. Post a SOAP message to a .NET web service.

3.1. Interoperability demo: consume my JWSDP RCX web service with Perl/cgi and SOAP::Lite.

The next step of my little "tour" about SOAP client is going to allow us to create a web client using Perl. This section will focus on how to design the SOAP client web page (Perl/cgi) and assume you have a web server configured for Perl/cgi with SOAP::Lite.

The code explained in this section is implemented in my demo Perl/cgi SOAP client page, check here if on-line.

3.1.1. Consume a simple remote procedure

We start here by consuming my readLS() remote procedure, taking a string as param and returning a string. This example will work for my RCX web service (see here if on-line) and should work (as a template) for any Java WSDP (document/literal) web service. This is a document/literal operation style web service. So if you want to use this code as a template to consume a rpc/encoded web service, you will need to make some adaptations. Probably some simplifications: by accessing the wsdl at runtime, etc...

The same way, you can add the other simple call exposed by my wsdl interface: int readLSpercent(int) and float readTemp(int). See the code below:

# define the param needed by the procedures
my $var1 = SOAP::Data->type('int');

# initialize
$var1->name('int_1');
$var1->value(1);

# make the call
my $resultp = $client->readLSpercent($var1);
my $resultT = $client->readTemp($var1);

# show the result in the web page
print "<p><b>Method readLSpercent()</b> value: " . $resultp->result();
print "<p><b>Method readTemp()</b> value: " . $resultT->result();

I will also cover here the case of a remote procedure returning an object, my method rcxResponse status(), returning the object rcxResponse, see here for a description of this object.

# no param here, so we can make the call
my $resultrr = $client->status();

# Parse the object returned (in $resultrr)
# with simple Perl code.
print "<p><b>Method status():</b> return my object <u>rcxResponse</u><table>";

my $rcxResponse = $resultrr->result;

foreach my $key (keys %{$rcxResponse}) {
  print "<tr><td>$key</td><td>" . $rcxResponse->{$key} . "</td></tr>";
}
print "</table>";

Next section we will see how to handle remote procedure returning array of simple type and array of object.

3.1.2. Consume a remote procedure returning arrays with SOAP::Lite

A little more difficult now, how to parse arrays returned by web service with SOAP::Lite. We will have to use a technique similar to XPath to read the value returned in the SOAP message. The remote procedure consumed here are collInt() (returning an array of int) and collPos() (returning an array of PosCol object). The PosCol class contain just two simple int variable XPos and YPos. Let's see how to handle these cases:

# Again, no param here so we make the call
my $resultci = $client->collInt();
my $resultcp = $client->collPos();

print "<p><b>Method collInt():</b> return an array of int<br>";

# To understand this code we have to know the structure of
# the SOAP message (the response) returned by the web service
# If you take a look at the wsdl, you will find for the operation
# collInt the complex type collIntResponse, composed with an array
# of result (int) element.
# Another way is to build a classic client with your preferred language
# and catch the SOAP message returned by the web service, see
# TcpTunnelGui tool. So you know
# exactly the structure of the values.
my @intarr = $resultci->valueof('//collIntResponse/result');

# A simple foreach read the array
foreach my $intval (@intarr) {
  print "elem: $intval<br>";
}

# Use the same method to parse the array of PosCol object
print "<p><b>Method collPos():</b> return an array of object <u>PosCol</u><table>";

my @poscolarr = $resultcp->valueof('//collPosResponse/result');
foreach my $pcval (@poscolarr) {
  print "<tr><td>object -> </td>";

  # Here, for each object you can list the key/value elements
  # using usual Perl code
  foreach my $keyval (keys %{$pcval}) {
    print "<td>$keyval: </td><td>" . $pcval->{$keyval} . "  </td>";
  }
  print "</tr>";
}
print "</table>";

So, creating a SOAP client with SAOP::Lite, for a Java WSDP (document/literal) web service wasn't so difficult. You just need to know how to parse the SOAP message returned by the web service when the return type is an object represented by an xml structure. A tool like TcpTunnelGui will help you to understand the structure of the return message. Next section, I will show you another interoperability demo: consume a .NET (still document/literal) web service with SOAP::Lite. And there, navigate in the structure of the xml response will be a little more tricky. Plus you will have to format an object to send as param. Enjoy!