2010-05-18 95 views
4

我想對本地Web服務進行SOAP調用。 Web服務是通過WSDL文件定義的(請參見下文)。我想使用Perl和SOAP :: Lite。我試過了:使用Perl的SOAP :: Lite和WSDL文件進行SOAP調用

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"; 

但是,這會導致XML parsing failed錯誤消息。什麼是正確的SOAP :: Lite代碼來調用此方法?

通過上述生成的HTTP請求是

Accept: text/xml 
Accept: multipart/* 
Accept: application/soap 
Content-Length: 553 
Content-Type: text/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> 

這裏是WSDL文件中定義的Web服務:

<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> 

回答

1

看起來這是一歲左右,所以這可能不是不再相關。總之,基於CPAN肥皂::精簡版文檔,它看起來像你想這樣做:

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"; 
2

既然你有WSDL,你不應該來構建SOAP ::數據對象都沒有。只需將WSDL加載到客戶端對象並直接調用該方法:

my $client = SOAP::WSDL->new(wsdl => $url_of_wsdl); 
my $result = $client->$method(@arguments); 

是的,就這麼簡單!