Warum wird der Namespace „WSDL“ in Aktionsnamen eingebunden, wenn sie Savon für die Ruby -Seifenkommunikation verwenden?

StackOverflow https://stackoverflow.com/questions/2294325

  •  21-09-2019
  •  | 
  •  

Frage

Ich versuche, auf einen Seifendienst zuzugreifen, den ich nicht kontrolliere. Eine der Handlungen heißt ProcessMessage. Ich habe dem Beispiel gefolgt und eine SOAP -Anfrage erstellt, aber ich habe einen Fehler zurückgelegt, in dem ich sagte, dass die Aktion nicht existiert. Ich habe das Problem auf die Art und Weise zurückgeführt, wie der Körper des Umschlags erzeugt wird.

<env:Envelope ... ">
    <env:Header>
        <wsse:Security ... ">
            <wsse:UsernameToken ...">
                <wsse:Username>USER</wsse:Username>
                    <wsse:Nonce>658e702d5feff1777a6c741847239eb5d6d86e48</wsse:Nonce>
                    <wsu:Created>2010-02-18T02:05:25Z</wsu:Created>
                    <wsse:Password ... >password</wsse:Password>
            </wsse:UsernameToken>
        </wsse:Security>
    </env:Header>
    <env:Body>
        <wsdl:ProcessMessage>
            <payload>
                ......
            </payload>
        </wsdl:ProcessMessage>
    </env:Body>
</env:Envelope>     

Dass ProcessMessage Tag sollte sein:

    <ProcessMessage xmlns="http://www.starstandards.org/webservices/2005/10/transport">

Das ist es, wenn es von der Beispiel -Java -App generiert wird und es funktioniert. Dieses Tag ist der einzige Unterschied zwischen dem, was meine Ruby -App generiert, und der Beispiel -Java -App. Gibt es eine Möglichkeit, die loszuwerden? "wsdl:" Namespace vor diesem einen Tag und fügen Sie ein solches Attribut hinzu. Gibt es eine Möglichkeit, die Handlung zu zwingen, nicht nur als Schnur wie der Rest des Körpers zu erzeugen?

Hier ist mein Code:

require 'rubygems'
require 'savon'
client = Savon::Client.new "https://gmservices.pp.gm.com/ProcessMessage?wsdl"

response = client.process_message! do | soap, wsse |
wsse.username = "USER"
wsse.password = "password"
soap.namespace = "http://www.starstandards.org/webservices/2005/10/transport" #makes no difference
soap.action = "ProcessMessage" #makes no difference
soap.input = "ProcessMessage" #makes no difference

#my body at this point is jsut one big xml string

soap.body = "<payload>...</payload>" 
# putting <ProccessMessage> tag here doesn't help as it just creates a duplicate tag in the body, since Savon keeps interjecting  <wsdl:ProcessMessage> tag.

  end

Ich habe Handsoap ausprobiert, aber es unterstützt HTTPS nicht und ist verwirrend. Ich habe SOAP4R ausprobiert, aber es ist noch verwirrender als Handsoap.

War es hilfreich?

Lösung 3

Steve, Sie sehen das WSDL: vor ProcessMessage -Tag? - Ich dachte, das war das einzige, was mich wegwirft, aber es ist nicht (übrigens ist es in Savon Lib in Savon Lib in Zeile 160 schwer in SOAP.RB). Auch wenn ich es nicht in SOAP.NamePaces -Voraussetzungen für den letzten XML erzeugt und angehängt wird. Das ist nicht von meinem Dienst gestattet.

Während das generierte XML eine gültige XML ist - ist sie nicht vollständig durch die Anforderungen des Dienstes, mit dem ich sprechen möchte. Dh: in erzeugter xml,

<?xml version="1.0" encoding="UTF-8"?>

Tag fehlt auch, ich brauche PayloadManifest im Header, und ich brauche WSU: Erstellt und WSU: Läuft in meinem WSSE: Tag ab, aber sie werden nicht implementiert usw. usw. Eine Reihe anderer kleiner Macken, die zu spezifisch sind zu meinem Fall. SOAP hat jedoch eine private Methode = xml_body. Auch die SOAP LIB in to_xml -Methode prüft, ob @xml_body bereits eingestellt wurde, bevor es sein eigenes XML generiert. Also modifizierte ich das Verhalten der Seife. durch Herstellung von SOAP.xml_body = öffentlich zugänglich. Also konnte ich es tun:

response = client.process_message! do |soap| 
soap.action = "http://www.starstandards.org/webservices/2005/10/transport/operations/ProcessMessage"
soap.xml_body = "MY XML STRING GENERATED ELSEWHERE GOES HERE"
end

Was schließlich funktioniert !!!!

Ich werde dies Rubii vorschlagen - wenn diese Option verfügbar ist, die viele seltene Fälle löst - in dem Menschen ihre benutzerdefinierte XML generieren und den Rest von Savon Lib verwenden können.

Andere Tipps

Sie müssen ein Array an SOAP übergeben. Geben Sie das zweite Element ein, dessen Hash die Namespace -Details enthält.

soap.input = [ 
  "ProcessMessage", 
  {"xmlns" => "http://www.starstandards.org/webservices/2005/10/transport"}
]

Dies sollte sicherstellen, dass Sie die Erklärung des Namensraums als Attribut für das Hauptelement erhalten.

Sie werden wahrscheinlich auch eine Namespace -Erklärung vor dem Element wie so erhalten

<env:Body>
    <wsdl:ProcessMessage xmlns="........." >
        <payload>
            ......
        </payload>
    </wsdl:ProcessMessage>
</env:Body>

Dies war jedoch kein Problem für mich, es war das Fehlen des Namespace -Attributs, das das Problem war, nicht das Vorhandensein des Namespace vor dem Element.

Für meinen Webdienst musste ich das loswerden "wsdl" Namespace über Steves Lösung.

Getestet mit Savon 0.9.6:

client = Savon::Client.new "https://example.com/webservice/account.asmx?WSDL"
response = client.request "GetAccount" do
  # Gotcha 1: set default namespace for body elements
  soap.input = ["GetAccount", {"xmlns" => "https://example.com/webservice/"}]
  soap.body = {
    "AccountID" => 1234
  }
  # Gotcha 2: get rid of namespace declaration of body elements
  soap.element_form_default = :unqualified
  # Gotcha 3: set SOAPAction different from default
  http.headers["SOAPAction"] = '"https://example.com/webservice/GetAccount"'
end
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top