2017-07-07 53 views
5

Próbuję wykonać bardzo złożone wywołanie SOAP w projekcie railsowym przy użyciu Savon.rb. Co najmniej tak skomplikowane, że konstruktorzy Savona mają duży problem, więc postanowiłem bezpośrednio zmodyfikować: xml.Wywołanie SOAP w Ruby on Rails przy użyciu Savona robi się dziwaczne wokół koperty i głównej operacji

Przede zainicjować klienta:

@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') 

Potem wykonać połączenie w kształcie:

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

dodaję prawidłowo sformatowany l Time.now, format: :postnl_api ciąg, a reszta jest nadal ciężko kodowane. W tym numer wiadomości.

Poniżej przedstawiono, w jaki sposób wywołanie zostało wykonane przez Savona w tym przypadku, pobrane za pomocą @request.body.

Wywołanie SOAP w mojej aplikacji

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

Następnie po to jak rozmowa powinna wyglądać jak widziałem ten jeden posiadający sukces w środowisku piaskownicy firmy.

Wywołanie SOAP, jak powinno być

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

Główną rzeczą, która wydaje się być wyłączony (i było to również w przypadku korzystania z generatora Savon btw) to envelope „s atrybuty, a głównym kształt obiektu i jego atrybuty. Nie rozumiem, dlaczego otrzymałem przedrostek wsdl: przed GenerateBarcode.

Mówię Savonowi, aby wziął mój xml i zbudował go dokładnie tak, ale to nie działa. Wysyłanie mojej wersji jako-zwraca błąd o numerze .

EDIT użyciu Chrisa jego strony

Korzystanie @Chris jego odpowiedź byłem w stanie wykonać następujące połączenia:

Skonfiguruj połączenie

@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"}) 

połączeń

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

Response:

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

której wersji Savona używasz? – Chris

+0

wersja 2, czy polecasz 3 już? –

Odpowiedz

1

Ok to działa (zweryfikowane)

@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"}) 

Więc trik został dodanie :namespace_identifier => nil i wysyłanie attributes. Ustawienie parametru namespace_identifier powoduje usunięcie wsdl z GenerateBarcode ans atrybutów ustawia niektóre przestrzenie nazw w tagu GenerateBarcode.Teraz pamiętam, dlaczego tak bardzo nienawidzę SOAP :(

+0

Dziękuję bardzo za podjęcie wysiłku, aby przyjrzeć się mojemu problemowi. starsze odpowiedzi Udało mi się nawiązać połączenie i uzyskać odpowiedź, którą umieściłem w powyższej edycji. Moje hasło hash do piaskownicy to "098fd559930983af31ef6630a0bb0c1974156561" .Nie wiem, gdzie leży błąd .. –

+0

Ok zaktualizowałem moją odpowiedź, ten kod działa dla mnie! – Chris

+0

Bardzo dziękuję, niestety, nagroda wygasła i z jakiegoś powodu mogę teraz wybrać tylko 100 ... przepraszam za to, tak czy inaczej, wygasła –