significado rails log example ruby soap savon

rails - ¿Por qué se interpone el espacio de nombre "wsdl" en el nombre de la acción cuando se utiliza savon para la comunicación de ruby ​​soap?



soap4r (3)

Estoy intentando acceder a un servicio SOAP que no controlo. Una de las acciones se llama ProcessMessage . Seguí el ejemplo y generé una solicitud SOAP, pero recibí un error diciendo que la acción no existe. Indagué el problema en la forma en que se genera el cuerpo del sobre.

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

Esa etiqueta de ProcessMessage debe ser:

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

Eso es lo que ocurre cuando la aplicación Java de ejemplo lo genera, y funciona. Esa etiqueta es la única diferencia entre lo que genera mi aplicación Ruby y la aplicación Java de muestra. ¿Hay alguna forma de deshacerse del espacio de nombres "wsdl:" frente a esa etiqueta y agregar un atributo como ese. Salvo eso, ¿hay alguna manera de forzar la acción para que no se genere simplemente pasando como una cadena como el resto del cuerpo?

Aquí está mi código:

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

Intenté handsoap pero no es compatible con HTTPS y es confuso. Intenté soap4r pero es aún más confuso que handsoap.


Debe pasar una matriz a soap.input cuyo segundo elemento es un hash que contiene los detalles del espacio de nombres.

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

Esto debería garantizar que termines con la declaración de espacio de nombre como un atributo para el elemento principal.

Probablemente también termines con una declaración de espacio de nombre antes del elemento como tal

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

pero esto no fue un problema para mí, fue la falta del atributo de espacio de nombres el problema, no la presencia del espacio de nombres antes del elemento.


Steve, ¿ves eso wsdl: frente a la etiqueta ProcessMessage? - Pensé que era lo único que me estaba tirando, pero no es así (por cierto, es difícil de encontrar en soap.rb en Savon lib en la línea 160). Eso incluso si no lo espacifico en soap.namespaces - es difícil de generar y se adjunta en el xml final. Lo cual no está permitido por mi servicio.

Mientras que el xml que se genera es un xml válido, no está completo por los requisitos del servicio con el que trato de hablar. Es decir: en xml generado,

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

falta la etiqueta, también, necesito PayloadManifest en el encabezado, además necesito wsu: created y wsu: expira en mi etiqueta wsse:, pero no están implementados, etc., etc. un montón de otras pequeñas peculiaridades que son demasiado específicas a mi caso Sin embargo, soap tiene un método privado = xml_body. También soap lib en el método to_xml está comprobando si @xml_body ya estaba configurado, antes de generar su propio xml. Así que terminé modificando levemente el comportamiento del jabón. haciendo soap.xml_body = accesible públicamente. Entonces pude hacer:

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

Lo cual finalmente funciona !!!!

Sugeriré esto a rubii, si esta opción está disponible, que resolverá muchos casos raros, donde las personas pueden generar su xml personalizado y usar el resto de savon lib.


Para mi servicio web, necesitaba deshacerme del espacio de nombre "wsdl" encima de la solución de Steve.

Probado 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