Почему пространство имен «WSDL» вмешивается в имя действия при использовании SAVON для связи с SAPON 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
Я попробовал Gersondoap, но он не поддерживает HTTPS и сбивает с толку. Я попробовал SOAP4R, но это еще более запутанно, чем руки.
Решение 3
Стив, вы видите, что WSDL: перед тегом ProcessMessage? - Я думал, что это было единственное, что меня выбрасывало, но это не так (кстати, это тяжело в Soap.rb в Savon Lib On Line 160). Что даже если я не буду пространственно это в мыле. Что не разрешено моим сервисом.
В то время как генерируемый XML является действительным XML - он не завершен требованием сервиса, с которой я пытаюсь поговорить. Т.е. в сгенерированном XML,
<?xml version="1.0" encoding="UTF-8"?>
Тэг отсутствует, также мне нужен PayLoadManifest в заголовке, плюс мне нужен WSU: создан и WSU: истекает в моем WSSE: TAG, но они не реализованы и т. Д., И т. Д. к моему делу. Однако у SOAP есть личный метод = XML_BODY. Также SOAP LIB в методе TO_XML проверяет, был ли уже установлен @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.
Другие советы
Вам нужно передать массив в SOAP. Второй элемент которого - хэш, содержащий детали пространства имен.
soap.input = [
"ProcessMessage",
{"xmlns" => "http://www.starstandards.org/webservices/2005/10/transport"}
]
Это должно убедиться, что вы получите объявление пространства имени в качестве атрибута к основному элементу.
Вы, вероятно, также получите объявление пространства имен перед элементом, таким
<env:Body>
<wsdl:ProcessMessage xmlns="........." >
<payload>
......
</payload>
</wsdl:ProcessMessage>
</env:Body>
Но это не было проблемой для меня, это было отсутствие атрибута пространства имен, которое было проблемой, а не наличием пространства имен перед элементом.
Для моего веб -сервиса мне нужно было избавиться от "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