为什么在使用savon进行ruby soap通信时,“wsdl”命名空间会插入操作名称?

我正在尝试访问我无法控制的SOAP服务。 其中一个操作称为ProcessMessage 。 我按照示例生成了一个SOAP请求,但是我收到一条错误,说该操作不存在。 我将问题追溯到信封体生成的方式。

     USER 658e702d5feff1777a6c741847239eb5d6d86e48 2010-02-18T02:05:25Z password       ......     

ProcessMessage标签应该是:

   

这就是样本Java应用程序生成它时的工作原理。 该标记是我的Ruby应用程序生成的示例和示例Java应用程序之间的唯一区别。 有没有办法摆脱那个标签前面的"wsdl:"命名空间并添加这样的属性。 除此之外,有没有办法强制动作不是通过像身体其他部分一样传递出来的?

这是我的代码:

 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 = "..." # putting  tag here doesn't help as it just creates a duplicate tag in the body, since Savon keeps interjecting  tag. end 

我尝试过handsoap但它不支持HTTPS并且令人困惑。 我试过soap4r,但它比handsoap更令人困惑。

您需要将数组传递给soap.input,其中第二个元素是包含命名空间详细信息的哈希。

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

这应该确保您最终将名称空间声明作为主元素的属性。

您可能也会在元素之前结束命名空间声明

    ......    

但这对我来说不是问题,缺少名称空间属性是问题,而不是元素之前存在命名空间。

对于我的Web服务,我需要摆脱Steve的解决方案之上的"wsdl"命名空间。

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

史蒂夫,你看到wsdl:在ProcessMessage标签前面? – 我认为那是唯一让我失望的东西,但事实并非如此(顺便说一下,它在第160行的Savon lib中的soap.rb中很难设置)。 即使我没有在soap.namespaces中将其区分开来 – 它也很难生成并附加在最终的xml中。 我的服务不允许这样做。

虽然生成的xml是一个有效的xml – 但是我想要与之交谈的服务的要求并不完整。 即:在生成的xml中,

  

标签丢失,而且,我需要在头文件中使用PayloadManifest,另外我需要wsu:created和wsu:在我的wsse:标签中过期,但它们没有实现等等等等一堆其他的小怪癖太具体了对我来说。 但是soap有一个私有方法= xml_body。 to_xml方法中的soap lib也在检查是否已经设置@xml_body,然后再生成它自己的xml。 所以我最后轻率地改变了肥皂的行为。 通过使soap.xml_body =可公开访问。 所以我能做到:

 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 

哪个终于有效!!!!

我建议使用rubii – 如果此选项可用,将解决很多罕见的情况 – 人们可以生成自定义xml并使用其余的savon lib。