2016-04-27 145 views
0

我正在使用PERL将Web服务调用到我们供应商提供的Web服务之一。 Web服务使用SOAP 1.2和WSHttpBinding。PERL WCF Web服务调用失败

我能够成功地调用Web服务中的大部分调用,除了RetrieveReport调用。 RetrieveReport调用应该是流式传输文件。不过,我收到了下面的回复。

调用RetrieveReport的一个示例是使用C#代码提及使用以下绑定提供的。不过,我不知道如何在PERL中做到这一点。如果任何人可以提供任何帮助,我提前感谢你。

C#应用程序配置结合

<binding name="WSHttpBinding_IBIStreamService" closeTimeout="00:02:00" 
        openTimeout="00:02:00" receiveTimeout="00:10:00" sendTimeout="00:10:00" 
        bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard" 
        maxBufferPoolSize="524288" maxReceivedMessageSize="2147483647" 
        messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true" 
        allowCookies="false"> 
        <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" 
         maxBytesPerRead="4096" maxNameTableCharCount="16384" /> 
        <reliableSession ordered="true" inactivityTimeout="00:10:00" 
         enabled="false" /> 
        <security mode="None"> 
         <transport clientCredentialType="Windows" proxyCredentialType="None" 
          realm="" /> 
         <message clientCredentialType="Windows" negotiateServiceCredential="true" /> 
        </security> 
       </binding> 

Perl代码

my $reportKey = 'report_key'; 
my $reportUri = 'report_uri'; 

my $xml = new XML::Simple; 
my $userAgent = LWP::UserAgent->new(agent => 'https://service.com/services/BIDataService'); 

my $message = <<'.'; 
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing"> 
    <s:Header> 
    <a:Action s:mustUnderstand="1">http://service.com/dataservices/bistream/2/IBIStreamService/RetrieveReport</a:Action> 
    <h:ReportKey xmlns:h="http://service.com/dataservices/bistream/2" xmlns="http://service.com/dataservices/bistream/2">[ReportKey]</h:ReportKey> 
    <a:To s:mustUnderstand="1">[ReportRetrievalUri]</a:To> 
    </s:Header> 
    <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <RetrieveReportRequest xmlns="http://service.com/dataservices/bistream/2" /> 
    </s:Body> 
    </s:Envelope> 
. 

# Replace the dynamic values 
$message =~ s/\[ReportKey\]/$reportKey/g; 
$message =~ s/\[ReportRetrievalUri\]/$reportUri/g; 

my $request = HTTP::Request->new(POST => $uri); 

$request->header(SOAPAction => '"http://service.com/dataservices/bistream/2/IBIStreamService/RetrieveReport"'); 
$request->content($message); 
$request->content_type("application/soap+xml; charset=utf-8"); 

print "-- CONTENT --\n\n"; 
print $request->content . "\n\n"; 

my $response = $userAgent->request($request); 

if ($response->is_success) { 
    print "--SUCCESS--\n" . $response->decoded_content . "\n"; 
} else { 
    print "--FAILURE--\n" . $response->status_line, "\n"; 
    print $response->error_as_HTML; 
} 

响应从卖方

<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing"> 
    <s:Header> 
     <a:Action s:mustUnderstand="1">http://www.w3.org/2005/08/addressing/fault</a:Action> 
    </s:Header> 
    <s:Body> 
     <s:Fault> 
      <s:Code> 
       <s:Value>s:Sender</s:Value> 
       <s:Subcode> 
        <s:Value>a:ActionNotSupported</s:Value> 
       </s:Subcode> 
      </s:Code> 
      <s:Reason> 
       <s:Text xml:lang="en-US">The message with Action \'http://service.com/dataservices/bistream/2/IBIStreamService/RetrieveReport\' cannot be processed at the receiver, due to a ContractFilter mismatch at the EndpointDispatcher. This may be because of either a contract mismatch (mismatched Actions between sender and receiver) or a binding/security mismatch between the sender and the receiver. Check that sender and receiver have the same contract and the same binding (including security requirements, e.g. Message, Transport, None).</s:Text> 
      </s:Reason> 
     </s:Fault> 
    </s:Body> 
</s:Envelope> 

WSDL来源

<?xml version="1.0" encoding="utf-8"?> 
<wsdl:definitions name="BIStreamService" targetNamespace="http://tempuri.org/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:tns="http://tempuri.org/" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex" xmlns:wsap="http://schemas.xmlsoap.org/ws/2004/08/addressing/policy" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:msc="http://schemas.microsoft.com/ws/2005/12/wsdl/contract" xmlns:i0="http://service.com/dataservices/bistream/2" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsa10="http://www.w3.org/2005/08/addressing" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata"> 
    <wsp:Policy wsu:Id="WSHttpBinding_IBIStreamService_policy"> 
     <wsp:ExactlyOne> 
      <wsp:All> 
       <wsaw:UsingAddressing/> 
      </wsp:All> 
     </wsp:ExactlyOne> 
    </wsp:Policy> 
    <wsdl:import namespace="http://service.com/dataservices/bistream/2" location="https://service.com/services/BIStreamingService?wsdl=wsdl0"/> 
    <wsdl:types/> 
    <wsdl:binding name="WSHttpBinding_IBIStreamService" type="i0:IBIStreamService"> 
     <wsp:PolicyReference URI="#WSHttpBinding_IBIStreamService_policy"/> 
     <soap12:binding transport="http://schemas.xmlsoap.org/soap/http"/> 
     <wsdl:operation name="RetrieveReport"> 
      <soap12:operation soapAction="http://service.com/dataservices/bistream/2/IBIStreamService/RetrieveReport" style="document"/> 
      <wsdl:input name="RetrieveReportRequest"> 
       <soap12:header message="i0:RetrieveReportRequest_Headers" part="ReportKey" use="literal"/> 
       <soap12:body use="literal"/> 
      </wsdl:input> 
      <wsdl:output name="StreamReportResponse"> 
       <soap12:header message="i0:StreamReportResponse_Headers" part="Status" use="literal"/> 
       <soap12:header message="i0:StreamReportResponse_Headers" part="StatusMessage" use="literal"/> 
       <soap12:body use="literal"/> 
      </wsdl:output> 
     </wsdl:operation> 
    </wsdl:binding> 
    <wsdl:binding name="BasicHttpBinding_IBIStreamService" type="i0:IBIStreamService"> 
     <soap:binding transport="http://schemas.xmlsoap.org/soap/http"/> 
     <wsdl:operation name="RetrieveReport"> 
      <soap:operation soapAction="http://service.com/dataservices/bistream/2/IBIStreamService/RetrieveReport" style="document"/> 
      <wsdl:input name="RetrieveReportRequest"> 
       <soap:header message="i0:RetrieveReportRequest_Headers" part="ReportKey" use="literal"/> 
       <soap:body use="literal"/> 
      </wsdl:input> 
      <wsdl:output name="StreamReportResponse"> 
       <soap:header message="i0:StreamReportResponse_Headers" part="Status" use="literal"/> 
       <soap:header message="i0:StreamReportResponse_Headers" part="StatusMessage" use="literal"/> 
       <soap:body use="literal"/> 
      </wsdl:output> 
     </wsdl:operation> 
    </wsdl:binding> 
    <wsdl:service name="BIStreamService"> 
     <wsdl:port name="WSHttpBinding_IBIStreamService" binding="tns:WSHttpBinding_IBIStreamService"> 
      <soap12:address location="https://service.com/services/BIStreamingService"/> 
      <wsa10:EndpointReference> 
       <wsa10:Address>https://service.com/services/BIStreamingService</wsa10:Address> 
      </wsa10:EndpointReference> 
     </wsdl:port> 
     <wsdl:port name="BasicHttpBinding_IBIStreamService" binding="tns:BasicHttpBinding_IBIStreamService"> 
      <soap:address location="https://service.com/services/BIStreamingService"/> 
     </wsdl:port> 
    </wsdl:service> 
</wsdl:definitions> 
+0

用LWP手工操作SOAP非常困难。为什么不使用[XML :: Compile :: WSDL](https://metacpan.org/pod/distribution/XML-Compile-WSDL11/lib/XML/Compile/WSDL11.pod)或[SOAP :: Lite ](http://p3rl.org/SOAP::Lite)呢? – simbabque

+0

我有几个安装XML :: Compile :: WSDL的问题。我尝试了SOAP :: Lite,但供应商的Web服务是非常自定义的,我很难让它在SOAP :: Lite中正常工作。提供完整的XML代码更容易,提交并用LWP解析它。 –

回答

0

我发现了问题。

报表Web服务有两个URL。一个执行报告,另一个执行报告检索。我修改了LWP :: UserAgent-> new(agent =>'')和HTTP :: Request-> new(POST =>''),在检索报告时指向https://service.com/services/BIStreamingService,现在它工作。

谢谢!