使用Savon的Ruby on Rails中的SOAP调用在信封和主要操作中变得很奇怪

问题描述:

在使用Savon.rb的rails项目中,我试图做出非常复杂的SOAP调用。至少复杂的萨翁建设者很麻烦,所以我决定直接操纵:xml。使用Savon的Ruby on Rails中的SOAP调用在信封和主要操作中变得很奇怪

的我第一次启动客户端:

@client = Savon.client(
      :endpoint => 'https://testservice.postnl.com/CIF_SB/BarcodeWebService/1_1/BarcodeWebService.svc', 
      :wsdl  => 'https://testservice.postnl.com/CIF_SB/BarcodeWebService/1_1/?wsdl') 

然后我打这个电话的形状:

@request = @client.build_request(:generate_barcode, 
      xml: %Q{ ... see soap call (with ruby interpolation) ... } 

我添加了一个正确格式化l Time.now, format: :postnl_api串,其余仍硬编码。包括消息号码。

以下是萨翁在这种情况下实际进行的调用的方式,使用@request.body进行检索。

SOAP调用我的应用程序

<?xml version="1.0" encoding="UTF-8"?> 
<s:Envelope 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:wsdl="http://tempuri.org/" 
    xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> 
    <s:Header> 
    <Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://postnl.nl/cif/services/BarcodeWebService/IBarcodeWebService/GenerateBarcode 
    </Action> 
    <Security xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"> 
     <UsernameToken> 
     <Username>devc_!R4xc8p9</Username> 
     <Password>xxxxxxxx</Password> 
     </UsernameToken> 
    </Security> 
    </s:Header> 
    <s:Body> 
    <wsdl:GenerateBarcode> 
     <d6p1:Customer> 
     <d6p1:CustomerCode>DEVC</d6p1:CustomerCode> 
     <d6p1:CustomerNumber>11223344</d6p1:CustomerNumber> 
     </d6p1:Customer> 
     <d6p1:Barcode> 
     <d6p1:Type>3S</d6p1:Type> 
     <d6p1:Range>DEVC</d6p1:Range> 
     <d6p1:Serie>1000000-2000000</d6p1:Serie> 
     </d6p1:Barcode> 
    </wsdl:GenerateBarcode> 
    </s:Body> 
</s:Envelope> 

再下面是一个电话应该是什么样子,因为我已经看到了这个有一个在公司的沙箱环境中取得成功。

SOAP调用,因为它应该是

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> 
    <s:Header> 
    <Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://postnl.nl/cif/services/BarcodeWebService/IBarcodeWebService/GenerateBarcode</Action> 
    <Security xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"> 
     <wsse:UsernameToken xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"> 
     <wsse:Username>devc_!R4xc8p9</wsse:Username> 
     <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">xxxxxxxx</wsse:Password> 
     </wsse:UsernameToken> 
    </Security> 
    </s:Header> 
    <s:Body> 
    <GenerateBarcode xmlns:d6p1="http://postnl.nl/cif/domain/BarcodeWebService/" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://postnl.nl/cif/services/BarcodeWebService/"> 
     <d6p1:Message> 
     <d6p1:MessageID>5</d6p1:MessageID> 
     <d6p1:MessageTimeStamp>28-06-2017 14:15:41</d6p1:MessageTimeStamp> 
     </d6p1:Message> 
     <d6p1:Customer> 
     <d6p1:CustomerCode>DEVC</d6p1:CustomerCode> 
     <d6p1:CustomerNumber>11223344</d6p1:CustomerNumber> 
     </d6p1:Customer> 
     <d6p1:Barcode> 
     <d6p1:Type>3S</d6p1:Type> 
     <d6p1:Range>DEVC</d6p1:Range> 
     <d6p1:Serie>1000000-2000000</d6p1:Serie> 
     </d6p1:Barcode> 
    </GenerateBarcode> 
    </s:Body> 
</s:Envelope> 

,这似乎是关(同时这也是使用萨翁建设者BTW的情况下),最主要的是envelope的属性和主操作的:generate_barcode形状以及它的属性。我不明白为什么我在GenerateBarcode之前得到前缀wsdl:

我告诉Savon采取我的xml和建立它完全一样,但它不起作用。按原样发送我的版本返回错误400。克里斯利用他的部分

编辑

使用@克里斯他的回答,我能够做以下电话:

设置呼叫

@client = Savon.client(
       :endpoint    => 'https://testservice.postnl.com/CIF_SB/BarcodeWebService/1_1/BarcodeWebService.svc', 
       :wsdl     => 'https://testservice.postnl.com/CIF_SB/BarcodeWebService/1_1/?wsdl', 
       :log      => true, 
       :wsse_auth    => [ENV['postnl_username'], ENV['postnl_password']], 
       :pretty_print_xml  => true, 
       :convert_request_keys_to => :camelcase, 
       :env_namespace   => :s) 

    message = { 
        "d6p1:Message" => { 
        "d6p1:MessageID" => "7", 
        "d6p1:MessageTimeStamp" => I18n.l(Time.now, format: :postnl_api) 
       }, 
        "d6p1:Customer" => { 
        "d6p1:CustomerCode" => "DEVC", 
        "d6p1:CustomerNumber" => "11223344"}, 
        "d6p1:Barcode" => { 
         "d6p1:Type" => "3S", 
         "d6p1:Range" => "DEVC", 
         "d6p1:Serie" => "1000000-2000000" } 
       } 
    @client.call(:generate_barcode, :message => message, :soap_header => { "Action" => "http://postnl.nl/cif/services/BarcodeWebService/IBarcodeWebService/GenerateBarcode"}) 

呼叫

<?xml version="1.0" encoding="UTF-8"?> 
<s:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:wsdl="http://tempuri.org/" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> 
    <s:Header> 
    <Action>http://postnl.nl/cif/services/BarcodeWebService/IBarcodeWebService/GenerateBarcode</Action> 
    <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"> 
     <wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="UsernameToken-1"> 
     <wsse:Username>devc_!R4xc8p9</wsse:Username> 
     <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">098fd559930983af31ef6630a0bb0c1974156561</wsse:Password> 
     </wsse:UsernameToken> 
    </wsse:Security> 
    </s:Header> 
    <s:Body> 
    <wsdl:GenerateBarcode> 
     <d6p1:Message> 
     <d6p1:MessageID>7</d6p1:MessageID> 
     <d6p1:MessageTimeStamp>17-07-2017 22:13:35</d6p1:MessageTimeStamp> 
     </d6p1:Message> 
     <d6p1:Customer> 
     <d6p1:CustomerCode>DEVC</d6p1:CustomerCode> 
     <d6p1:CustomerNumber>11223344</d6p1:CustomerNumber> 
     </d6p1:Customer> 
     <d6p1:Barcode> 
     <d6p1:Type>3S</d6p1:Type> 
     <d6p1:Range>DEVC</d6p1:Range> 
     <d6p1:Serie>1000000-2000000</d6p1:Serie> 
     </d6p1:Barcode> 
    </wsdl:GenerateBarcode> 
    </s:Body> 
</s:Envelope> 

响应

<?xml version="1.0"?> 
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> 
    <s:Body> 
    <s:Fault> 
     <faultcode xmlns:a="http://schemas.microsoft.com/net/2005/12/windowscommunicationfoundation/dispatcher">a:InternalServiceFault</faultcode> 
     <faultstring xml:lang="en-US">The server was unable to process the request due to an internal error. For more information about the error, either turn on IncludeExceptionDetailInFaults (either from ServiceBehaviorAttribute or from the &lt;serviceDebug&gt; configuration behavior) on the server in order to send the exception information back to the client, or turn on tracing as per the Microsoft .NET Framework SDK documentation and inspect the server trace logs.</faultstring> 
    </s:Fault> 
    </s:Body> 
</s:Envelope> 
+0

你使用的是哪种版本的savon? – Chris

+0

版本2,你是否已经推荐3款? –

好这个工程(认证)

@client = Savon.client(
      :wsdl     => 'https://testservice.postnl.com/CIF_SB/BarcodeWebService/1_1/?wsdl', 
      :log      => true, 
      :wsse_auth    => ['devc_!R4xc8p9', 'xxx'], 
      :pretty_print_xml  => true, 
      :convert_request_keys_to => :camelcase, 
      :env_namespace   => :s, 
      :namespace_identifier => nil 
      ) 

message = { 
       "d6p1:Message" => { 
       "d6p1:MessageID" => "10", 
       "d6p1:MessageTimeStamp" => Time.now.strftime("%d-%m-%Y %H:%M:%S") 
      }, 
       "d6p1:Customer" => { 
       "d6p1:CustomerCode" => "DEVC", 
       "d6p1:CustomerNumber" => "11223344"}, 
       "d6p1:Barcode" => { 
        "d6p1:Type" => "3S", 
        "d6p1:Range" => "DEVC", 
        "d6p1:Serie" => "1000000-2000000" } 
      } 


attributes = { "xmlns:d6p1" => "http://postnl.nl/cif/domain/BarcodeWebService/", 
       "xmlns:i" => "http://www.w3.org/2001/XMLSchema-instance", 
       "xmlns" => "http://postnl.nl/cif/services/BarcodeWebService/"} 

@client.call(:generate_barcode, :attributes => attributes, 
      :message => message, 
      :soap_header => { "Action" => "http://postnl.nl/cif/services/BarcodeWebService/IBarcodeWebService/GenerateBarcode"}) 

因此,关键是加入:namespace_identifier => nil和发送attributes。设置namespace_identifier会从GenerateBarcode中删除wsdl,ans属性会在GenerateBarcode标记上设置一些名称空间。现在我记得为什么我非常讨厌SOAP:(

+0

非常感谢你付出努力来研究我的问题。旧的答案我可以拨打电话,并获得我在上面编辑的回复,我的沙箱密码哈希是'098fd559930983af31ef6630a0bb0c1974156561',不知道哪里出问题了, –

+0

Ok更新了我的回答,这段代码适合我! – Chris

+0

非常感谢你!不幸的是,这个赏金过期了,出于某种原因,我现在只能选择100 ...对不起,无论如何,它已经过期。 –