为什么是;wsdl";在使用savon进行ruby soap通信时,命名空间被插入到操作名中?
我正在尝试访问一个我无法控制的SOAP服务。其中一个操作称为为什么是;wsdl";在使用savon进行ruby soap通信时,命名空间被插入到操作名中?,ruby,soap,savon,Ruby,Soap,Savon,我正在尝试访问一个我无法控制的SOAP服务。其中一个操作称为ProcessMessage。我按照这个示例生成了一个SOAP请求,但是我得到了一个错误,说该操作不存在。我将问题追溯到信封主体的生成方式 <env:Envelope ... "> <env:Header> <wsse:Security ... "> <wsse:UsernameToken ..."> <
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>
当它由示例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
需要“rubygems”
需要“savon”
client=Savon::client.new“https://gmservices.pp.gm.com/ProcessMessage?wsdl"
响应=client.process\u消息!do | soap,wsse|
wsse.username=“用户”
wsse.password=“password”
soap.namespace=”http://www.starstandards.org/webservices/2005/10/transport“#没什么区别
soap.action=“ProcessMessage”没有区别
soap.input=“ProcessMessage”#没有区别
#此时我的主体是jsut一个大xml字符串
soap.body=“…”
#把标签放在这里并没有帮助,因为它只是在身体中创建了一个重复的标签,因为Savon一直在插入标签。
结束
我尝试了handsoap,但它不支持HTTPS,而且令人困惑。我尝试了soap4r,但它比handsoap更令人困惑。您需要向soap传递一个数组。输入第二个元素是包含名称空间详细信息的哈希
soap.input = [
"ProcessMessage",
{"xmlns" => "http://www.starstandards.org/webservices/2005/10/transport"}
]
这将确保最终将名称空间声明作为主元素的属性
您可能还将在元素前面声明一个名称空间,如下所示
<env:Body>
<wsdl:ProcessMessage xmlns="........." >
<payload>
......
</payload>
</wsdl:ProcessMessage>
</env:Body>
......
但这对我来说不是问题,问题在于缺少namespace属性,而不是元素前面是否存在名称空间。Steve,您看到了wsdl:在ProcessMessage标记前面吗?-我认为这是唯一让我感到不快的事情,但事实并非如此(顺便说一句,在Savon lib的第160行的soap.rb中它是硬设置的)。即使我没有在soap.namespace中指定它,它也很难生成并附加到最终的xml中。这是我的服务不允许的 虽然生成的xml是一个有效的xml,但根据我试图与之交谈的服务的要求,它并不完整。即:在生成的xml中
<?xml version="1.0" encoding="UTF-8"?>
这终于奏效了
我将向rubii建议这一点——如果这个选项可用,它将解决许多罕见的情况——人们可以生成自定义xml并使用savon库的其余部分 对于我的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>
</wsdl:ProcessMessage>
在Savon 2进行了测试。这张票在以下位置打开:嗨,尼克,我看到了同样的问题,你有什么进展吗?嗨,史蒂夫。我把项目的这一部分放在等待状态,因为还有其他更重要的功能需要实现,这是一个“很好拥有”的列表。今天晚些时候我会尝试你的解决方案,看看是否有效。谢谢你让我知道你!史提夫。谢谢你的留言-这不是我的解决方案,但它让我更仔细地思考和查看日志。看看我自己的答案。评论中没有足够的空间。:-)谢谢你的解决方案在我遇到同样的问题时很有魅力。你的解决方案对我很有效。我错过了行动中的xmlns!我仍然在主体中获得wsdl:namespace,但它不会影响SOAP请求。我认为这是一个很好的解决方案。我发现IIS/.net抱怨缺少名称空间,但并不关心文件顶部是否有指令。祝你好运,到那一步是相当痛苦的。
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>
</wsdl:ProcessMessage>
client = Savon.client(
:no_message_tag => true
)