I want to make a SOAP call to a local web service. The web service is defined via a WSDL file (see below). I want to use Perl and SOAP::Lite. I tried this:
use strict ;
use warnings ;
use SOAP::Lite ;
my $endpoint = qq{http://example.com:2222/orawsv/PS_API/ACCOUNT_WS} ;
my $tns = 'http://xmlns.oracle.com/orawsv/PS_API/ACCOUNT_WS' ;
my $method_urn = $tns ;
my $soapaction = $tns ;
my $method = 'GET_BY_ACCOUNT_NUMBER' ;
my $sObj = SOAP::Lite->new(uri => $soapaction, proxy => $endpoint) ;
my $response = $sObj->call(SOAP::Data->name($method)->attr({ 'xmlns' => $method_urn})
=> SOAP::Data->name('ACCOUNT_NUMBER-VARCHAR2-IN' => '274724')) ;
print $response->faultstring() . "\n";
However, this results in an XML parsing failed
error message. What would be the correct SOAP::Lite code to make this method call?
The HTTP request generated by the above is
Accept: text/xml
Accept: multipart/*
Accept: application/soap
Content-Length: 553
Content-Type: t开发者_JAVA技巧ext/xml; charset=utf-8
SOAPAction: "http://xmlns.oracle.com/orawsv/PS_API/ACCOUNT_WS#GET_BY_ACCOUNT_NUMBER"
<?xml version="1.0" encoding="UTF-8"?><soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<GET_BY_ACCOUNT_NUMBER xmlns="http://xmlns.oracle.com/orawsv/PS_API/ACCOUNT_WS">
<ACCOUNT_NUMBER-VARCHAR2-IN xsi:type="xsd:int">274724</ACCOUNT_NUMBER-VARCHAR2-IN>
</GET_BY_ACCOUNT_NUMBER>
</soap:Body>
</soap:Envelope>
Here is the WSDL file defining the web service:
<definitions name="ACCOUNT_WS"
targetNamespace="http://xmlns.oracle.com/orawsv/PS_API/ACCOUNT_WS"
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:tns="http://xmlns.oracle.com/orawsv/PS_API/ACCOUNT_WS"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
<types>
<xsd:schema targetNamespace="http://xmlns.oracle.com/orawsv/PS_API/ACCOUNT_WS" elementFormDefault="qualified">
<xsd:element name="CACCOUNT_A-GET_BY_ACCOUNT_NUMBERInput">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="ACCOUNT_NUMBER-VARCHAR2-IN" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="GET_BY_ACCOUNT_NUMBEROutput">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="RETURN" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
</types>
<message name="GET_BY_ACCOUNT_NUMBERInputMessage">
<part name="parameters" element="tns:CACCOUNT_A-GET_BY_ACCOUNT_NUMBERInput"/>
</message>
<message name="GET_BY_ACCOUNT_NUMBEROutputMessage">
<part name="parameters" element="tns:GET_BY_ACCOUNT_NUMBEROutput"/>
</message>
<portType name="ACCOUNT_WSPortType">
<operation name="GET_BY_ACCOUNT_NUMBER">
<input message="tns:GET_BY_ACCOUNT_NUMBERInputMessage"/>
<output message="tns:GET_BY_ACCOUNT_NUMBEROutputMessage"/>
</operation>
</portType>
<binding name="ACCOUNT_WSBinding" type="tns:ACCOUNT_WSPortType">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="GET_BY_ACCOUNT_NUMBER">
<soap:operation soapAction="GET_BY_ACCOUNT_NUMBER"/>
<input>
<soap:body parts="parameters" use="literal"/>
</input>
<output>
<soap:body parts="parameters" use="literal"/>
</output>
</operation>
</binding>
<service name="ACCOUNT_WSService">
<documentation>Oracle Web Service</documentation>
<port name="ACCOUNT_WSPort" binding="tns:ACCOUNT_WSBinding">
<soap:address location="http://example.com:2222/orawsv/PS_API/ACCOUNT_WS"/>
</port>
</service>
</definitions>
Since you have the WSDL, you shouldn't have to construct SOAP::Data objects at all. Simply load the WSDL into your client object and call the method directly:
my $client = SOAP::WSDL->new(wsdl => $url_of_wsdl);
my $result = $client->$method(@arguments);
Yes, it's that easy!
Looks like this is about a year old, so this might not be relevant any longer. Anyway, based on the soap::lite documentation on CPAN it looks like you want to do this:
my $response = $sObj->call(SOAP::Data->name($method)->attr({ 'xmlns' => $method_urn}),
SOAP::Data->name('parameters')->value(SOAP::Data->value([
SOAP::Data->name('ACCOUNT_NUMBER-VARCHAR2-IN' => '274724'),
]))
);
die $response->fault->{ faultstring } if ($response->fault);
print $response->result, "\n";
精彩评论