This section provides a tutorial example on how to use a SOAP::Lite client to reach a Web service end point with the proxy parameter. But the test failed because of incorrect SOAPAction value.
In previous SOAP::Lite tutorials, we learned how to create a simple dummy SOAP server,
create a simple SOAP client and make them work together.
Now let's try to write a SOAP::Lite client program to talk a real Web service provided by xmlme.com.
This Web service is offered at http://www.xmlme.com/WSShakespeare.asmx with this description:
"GetSpeech requires a string formatted phrase from one of Shakespeare's plays as input.
The speech, speaker, and play will be returned as an XML string.
Sample Shakespeare Phrases: To be, or not to be | ..."
Based on the above description I wrote my first version of GetSpeech.pl:
#- GetSpeech.pl
#- Copyright (c) 2009 by Dr. Herong Yang, herongyang.com
#- All rights reserved
#
use SOAP::Lite +trace;
my $client = SOAP::Lite->new();
$client->proxy('http://www.xmlme.com/WSShakespeare.asmx');
my $som = $client->GetSpeech("To be, or not to be");
my $output = $som->result;
print $output . "\n";
When executed, I got this:
\herong>GetSpeech.pl
SOAP::Transport::new: ()
SOAP::Serializer::new: ()
SOAP::Deserializer::new: ()
SOAP::Parser::new: ()
SOAP::Lite::new: ()
SOAP::Transport::HTTP::Client::new: ()
SOAP::Lite::call: ()
SOAP::Serializer::envelope: ()
SOAP::Serializer::envelope: GetSpeech To be, or not to be
...
SOAP::Transport::HTTP::Client::send_receive: HTTP::Request=HASH(0x...
SOAP::Transport::HTTP::Client::send_receive:
POST http://www.xmlme.com/WSShakespeare.asmx
Accept: text/xml
Accept: multipart/*
Content-Length: 479
Content-Type: text/xml; charset=utf-8
SOAPAction: "#GetSpeech"
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope
xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/1999/XMLSchema"
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<GetSpeech>
<c-gensym3 xsi:type="xsd:string">To be, or not to be</c-gensym3>
</GetSpeech>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
SOAP::Transport::HTTP::Client::send_receive: HTTP::Response=HASH(0...
SOAP::Transport::HTTP::Client::send_receive:
HTTP/1.1 500 Internal Server Error
Cache-Control: private
Connection: close
Date: ... 2009
Server: Microsoft-IIS/6.0
Content-Length: 1015
Content-Type: text/xml; charset=utf-8
Client-Date: ... 2009
Client-Response-Num: 1
X-AspNet-Version: 2.0.50727
X-Powered-By: ASP.NET
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<soap:Fault>
<faultcode>soap:Client</faultcode>
<faultstring>
System.Web.Services.Protocols.SoapException:
Server did not recognize the value of HTTP Header
SOAPAction: #GetSpeech.
at System.Web.Services.Protocols
.Soap11ServerProtocolHelper.RouteRequest()
...
</faultstring>
<detail />
</soap:Fault>
</soap:Body>
</soap:Envelope>
...
Obviously, the Web service server failed with a "HTTP/1.1 500 Internal Server Error".
It was actually caused by an exception in the Web service process:
"System.Web.Services.Protocols.SoapException: Server did not recognize the value
of HTTP Header SOAPAction: #GetSpeech."
Here is my quick analysis of the problem:
My test program, GetSpeech.pl generated a SOAP 1.1 request. See the header line of
'Content-Type: text/xml; charset=utf-8' and 'SOAPAction: "#GetSpeech"'.
The value "#GetSpeech" in the "SOAPAction" header line is wrong.
It should be "http://xmlme.com/WebServices/GetSpeech" according
to the instruction page at http://www.xmlme.com/WSShakespeare.asmx?op=GetSpeech.
One positive result of the test is that my test program did reach
the Web service end point at: http://www.xmlme.com/WSShakespeare.asmx.
I will modify my program to provide SOAPAction correctly in the next tutorial.