Search code examples
perlsoapapache-axisxml-namespacessoaplite

Perl - SOAP::Lite request not setting xmlns:soap with correct value on Axis2


I've just created a webservice client in Perl using SOAP::Lite.

I manage to invoke a method of my webservice quite easily, but for some unknown reasons, it works sometimes, and sometimes it won't work.

Here's my perl client code :

my $client = SOAP::Lite->uri("http://loa.webservice")
                        ->service("http://localhost:8888/LogAnalyzerWS/services/DataReceiver?wsdl");
my $res;
do {
    sleep(2);
    print ("ok \n");
    $res = $client->sendData($data);
}while(!defined $res);

print $res, "\n";

I tried to add a while loop to resend the data if the result is undefined, but it won't work.

After some analysis of SOAP::Lite trace log file, I found that during the request, one parameter changes.

Here's the correct xml soap request :

<?xml version="1.0" encoding="UTF-8"?>
    <soap:Envelope soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"     xmlns:ax21="http://metier.loa/xsd" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"     xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:ns="http://webservice.loa" xmlns:ns1="http://org.apache.axis2/xsd" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <soap:Body>
            <ns:sendData>
                <element xsi:type="xs:base64Binary">PD94bWwgdmVyc2lvbj0</element>
            </ns:sendData>
        </soap:Body>
    </soap:Envelope>

And the correct answer :

<?xml version='1.0' encoding='utf-8'?>
    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
    <soapenv:Body>
            <ns:sendDataResponse xmlns:ns="http://webservice.loa">
                <ns:return>1</ns:return>
        </ns:sendDataResponse>
    </soapenv:Body>
</soapenv:Envelope>

And here's the faulty xml request :

<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ax21="http://metier.loa/xsd" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:ns="http://webservice.loa" xmlns:ns1="http://org.apache.axis2/xsd" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <soap:Body>
        <ns:sendData>
            <element xsi:type="xs:base64Binary">PD94bWwgdmVyc2lvbj0</element>
        </ns:sendData>
    </soap:Body>
</soap:Envelope>

With the answer :

<?xml version='1.0' encoding='utf-8'?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
    <soapenv:Header xmlns:wsa="http://www.w3.org/2005/08/addressing">
        <wsa:Action>http://www.w3.org/2005/08/addressing/soap/fault</wsa:Action>
    </soapenv:Header>
    <soapenv:Body>
        <soapenv:Fault>
            <faultcode>soapenv:VersionMismatch</faultcode>
            <faultstring>Only SOAP 1.1 or SOAP 1.2 messages are supported in the system</faultstring>
            <detail />
        </soapenv:Fault>
    </soapenv:Body>
</soapenv:Envelope>

As you can see, xmlns:soap hasn't got the same value in the correct and the faulty request : for the correct one, it is :

"http://schemas.xmlsoap.org/soap/envelope/"

And for the faulty one, it is :

"http://schemas.xmlsoap.org/wsdl/soap/"

Any ideas why SOAP::Lite is changing this parameter on it's own ?


Solution

  • The problem comes from the way namespaces are handled in SOAP::Lite. See this issue on RT cpan. Axis 2 was generating a wsdl which was then parsed by SOAP::Lite, and the value of xmlns:soap from the hash, set by the SOAP::Lite::Serializer, was wrongly being modified by the parsing of the wsdl.

    To solve this problem, use this at the very begining of your code (before setting the wsdl in SOAP::Lite) :

    $SOAP::Constants::PREFIX_ENV = 'SOAP-ENV';