How to get SOAP::Lite working with the Apache CXF web service

I'm not going to spend too much time showing this Perl SOAP client solution, but if you're having problems using the Perl SOAP::Lite module as a client running against a modern web service, this sample Perl code may help solve the problem.

First, I'd like to show what my original Perl SOAP client code looked like when I was using it as a SOAP client running against several Axis and XFire web services:

#!/usr/bin/perl

use POSIX qw(setsid);
use POSIX qw(:sys_wait_h);
use SOAP::Lite;

sub send_event_to_web_service
{
  my $uri = 'http://service.acme.com';
  my $proxy = 'http://localhost:8080/services/FTPEventService';
  my $event = '127.0.0.1|proftpd|[26/Mar/2008:10:56:07 -0400]|STOR FOO.pdf|226|/ftp/FOO.pdf';

  print SOAP::Lite
    -> proxy($proxy)
    -> uri($uri)
    -> logFTPEvent($event)
    -> result;
}

&send_event_to_web_service();

# the end
exit(0);

(Note: All the names and URLs in that example have been changed for use in this example.)

As you can see that Perl SOAP client code is very simple and straightforward, no problems, it works fine with Apache Axis, Axis2, and XFire. It's really just boilerplate code straight from the SOAP::Lite cookbook.

Unfortunately it doesn't work with more modern SOAP web service frameworks -- specifically in my case the Apache CXF web service framework.

The short story is that to get SOAP::Lite to work with Apache CXF you'll need to change your Perl SOAP client code to look like this:

#!/usr/bin/perl

use POSIX qw(setsid);
use POSIX qw(:sys_wait_h);
use SOAP::Lite;

sub send_event_to_web_service
{
  my $uri = 'http://service.acme.com';
  my $proxy = 'http://localhost:8080/services/FTPEventService';
  my $event = '127.0.0.1|proftpd|[26/Mar/2008:10:56:07 -0400]|STOR FOO.pdf|226|/ftp/FOO.pdf';
  my $methodName = 'logFTPEvent';
  my $paramName = 'ftpEventString';

  $nmsp = $uri;
  $srvc = SOAP::Lite-> uri($nmsp) 
          ->proxy($proxy) 
          ->on_action (sub { return '' } ); 
  my $method = SOAP::Data->name("ns1:" . $methodName) 
          ->attr({'xmlns:ns1' => $nmsp}); 
  my @params = (SOAP::Data->name($paramName=>$event)); 
  print $srvc->call($method=>@params)->result; 
}

&send_event_to_web_service();

# the end
exit(0);

There are several things to say about this Perl SOAP client code (it's a lot uglier and more complicated), but the most important thing to say right now is that I didn't write it. I found most of the solution at this Nabble URL. I think the only thing I did with the code I found there was to add more variables to it to make it more flexible, and test it thoroughly with Apache CXF.

Finally, note that I haven't done any backwards compatibility testing to see if this Perl SOAP client code works with Axis or XFire.