Perché namespace “WSDL” intervenne in nome di azione quando si utilizza per la comunicazione savon rubino sapone?

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

  •  21-09-2019
  •  | 
  •  

Domanda

Sto cercando di accedere a un servizio SOAP non mi controllo. Una delle azioni è chiamato ProcessMessage. Ho seguito l'esempio e ha generato una richiesta SOAP, ma ho ottenuto un errore indietro dicendo che l'azione non esiste. Ho rintracciato il problema al modo in cui il corpo della busta viene generato.

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

Questo tag ProcessMessage dovrebbe essere:

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

Questo è quello che è quando si è generato dalla applicazione del campione di Java, e funziona. Questo tag è l'unica differenza tra quello che il mio Rubino app genera e l'applicazione di esempio Java. C'è un modo per sbarazzarsi dello spazio dei nomi "wsdl:" di fronte a quella di tag e aggiungere un attributo del genere. A parte ciò, c'è un modo per forzare l'azione di non essere essere generato semplicemente passato come una stringa come il resto del corpo?

Qui è il mio codice:

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

ho provato handsoap ma non supporta HTTPS ed è fonte di confusione. Ho provato soap4r ma ma è ancora più confusa di quanto handsoap.

È stato utile?

Soluzione 3

Steve, si vede che wsdl: davanti tag ProcessMessage? - Ho pensato che era l'unica cosa che mi è stato gettato via, ma la sua non è (a proposito è impostato duro in soap.rb in Savon lib on line 160). Che anche se non lo faccio spacify in soap.namespaces - è difficile generato e attaccato in XML finale. Il che non è consentita dal mio servizio.

Mentre l'xml che si genera è un XML valido - non è completa dai requirments del servizio che sto cercando di parlare. Cioè .: in XML generato,

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

tag non è presente, anche, ho bisogno PayloadManifest nell'intestazione, più ho bisogno di WSU: creato e WSU: scade nel mio wsse: tag, ma non sono implementate, ecc, ecc una serie di altri piccoli capricci che sono troppo specifiche per il mio caso. Tuttavia sapone ha un metodo privato = xml_body. Anche sapone lib nel metodo to_xml sta verificando se @xml_body era già impostato, prima di generare il proprio XML. Così ho finito leggermente modificare il comportamento di sapone. facendo soap.xml_body = pubblicamente accessibile. Così mi è stato in grado di fare:

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

Il che finalmente funziona !!!!

Io suggerisco questo per RuBii - se questa opzione diventa disponibile che risolverà un sacco di rari casi - dove le persone possono generare la loro XML personalizzato e utilizzare il resto del savon lib.

Altri suggerimenti

È necessario passare un array a soap.input il secondo elemento di cui è un hash che contiene i dettagli dello spazio dei nomi.

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

Questo dovrebbe garantire si finisce con la dichiarazione dello spazio nome di un attributo per l'elemento principale.

Si avrà probabilmente anche finire con una dichiarazione dello spazio dei nomi prima che l'elemento in questo modo

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

, ma questo non era un problema per me, era la mancanza di un attributo dello spazio dei nomi che è stato il problema, non la presenza dello spazio dei nomi prima che l'elemento.

Per il mio servizio web ho bisogno di sbarazzarsi dello spazio dei nomi "wsdl" in cima alla soluzione di Steve.

Testato con 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
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top