为什么“wsdl”是“wsdl”?使用 savon 进行 Ruby Soap 通信时,命名空间插入到操作名称中?
我正在尝试访问我无法控制的 SOAP 服务。其中一项操作称为 ProcessMessage。我按照示例生成了一个 SOAP 请求,但收到一条错误消息,指出该操作不存在。我将问题追溯到信封正文的生成方式。
<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>
该 ProcessMessage
标记应该是:
<ProcessMessage xmlns="http://www.starstandards.org/webservices/2005/10/transport">
这就是示例 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 = "<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
我尝试过handsoap,但它不支持HTTPS并且令人困惑。我尝试过soap4r,但它比handsoap 更令人困惑。
I'm trying to access a SOAP service I don't control. One of the actions is called ProcessMessage
. I followed the example and generated a SOAP request, but I got an error back saying that the action doesn't exist. I traced the problem to the way the body of the envelope is generated.
<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>
That ProcessMessage
tag should be:
<ProcessMessage xmlns="http://www.starstandards.org/webservices/2005/10/transport">
That's what it is when it is generated by the sample Java app, and it works. That tag is the only difference between what my Ruby app generates and the sample Java app. Is there any way to get rid of the "wsdl:"
namespace in front of that one tag and add an attribute like that. Barring that, is there a way to force the action to be not to be generated by just passed as a string like the rest of the body?
Here is my 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
I tried handsoap but it doesn't support HTTPS and is confusing. I tried soap4r but but it's even more confusing than handsoap.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您需要将一个数组传递给soap.input,其中第二个元素是包含命名空间详细信息的哈希。
这应该确保您最终将名称空间声明作为主元素的属性。
您可能还会在元素之前得到一个命名空间声明,就像这样,
但这对我来说不是问题,问题在于缺少命名空间属性,而不是元素之前存在命名空间。
You need to pass an array to soap.input the second element of which is a hash containing the namespace details.
This should ensure you end up with the name space declaration as an attribute to the main element.
You will probably also end up with a namespace declaration before the element like so
but this was not an issue for me, it was the lack of the namespace attribute that was the issue, not the presence of the namespace before the element.
对于我的 Web 服务,我需要摆脱 Steve 解决方案之上的
"wsdl"
命名空间。使用 Savon 0.9.6 进行测试:
For my web service I needed to get rid of the
"wsdl"
namespace on top of Steve's solution.Tested with Savon 0.9.6:
Steve,您看到 ProcessMessage 标记前面的 wsdl: 了吗? - 我以为这是唯一让我失望的事情,但事实并非如此(顺便说一句,它是在 Savon lib 中的soap.rb 第 160 行中硬设置的)。即使我不在soap.namespaces 中对其进行spacify,它也很难生成并附加在最终的xml 中。这是我的服务不允许的。
虽然生成的 xml 是有效的 xml,但它不符合我尝试与之交谈的服务的要求。即:在生成的 xml 中,
标签丢失,另外,我需要在标头中包含 PayloadManifest,另外我需要 wsu:created 和 wsu:expires 在我的 wsse: 标签中,但它们没有实现,等等,等等。对于我的情况来说,有些小怪癖太具体了。然而soap有一个私有方法= xml_body。 to_xml 方法中的soap lib 还在生成自己的xml 之前检查@xml_body 是否已设置。所以我最终稍微修改了肥皂的行为。通过使soap.xml_body = 可公开访问。所以我能够做到:
这终于有效了!!!
我会向 rubii 建议这个 - 如果这个选项可用,这将解决很多罕见的情况 - 人们可以生成他们的自定义 xml 并使用 savon lib 的其余部分。
Steve, you see that wsdl: in front of ProcessMessage tag? - I thought that was the only thing that was throwing me off but its not ( by the way it's hard set in soap.rb in Savon lib on line 160). That even if I don't spacify it in soap.namespaces - it's hard generated and attached in final xml. Which is not allowed by my service.
While the xml that is generated is a valid xml - it's not complete by the requirments of the service I'm trying to talk to. I.e.: in generated xml,
tag is missing, also, I need PayloadManifest in the header,plus I need wsu:created and wsu:expires in my wsse: tag, but they are not implemented, etc., etc. a bunch of other little quirks that are too specific to my case. However soap has a private method = xml_body. Also soap lib in to_xml method is checking whether @xml_body was already set, before generating it's own xml. So I ended up slighly modifying behavior of soap. by making soap.xml_body = publicly accessable. So I was able to do:
Which finally works!!!!
I'll suggest this to rubii - if this option becomes available that will solve a lot rare cases - where people can generate their custom xml and use the rest of savon lib.
我花了几个小时试图找到一个解决方案来摆脱:
这达到了我想要的效果:
在 Savon 2 中进行了测试。
I spent hours trying to find a solution to get rid of:
This does what I wanted:
Tested in Savon 2.