#ruby #soap #savon
#ruby #soap #savon
Вопрос:
Я пытаюсь сделать то, что кажется довольно простым SOAP
запросом, который работает, SoapUI
но когда я выполняю свой код Ruby, я получаю запрос на выполнение исключения raise_soap_and_http_errors!.
Вот код — документ, на который ссылается wsdl_path, работает в SOAPUI для выполнения запроса аутентификации.
require 'savon'
wsdl_path = 'XXXX_soap_interface.wsdl'
client = Savon.client(
:wsdl => wsdl_path,
:ssl_verify_mode => :none,
:raise_errors => true, # false if you don't want to see exceptions
pretty_print_xml: true)
response = client.call(
:authenticate,
message: {:partnerName => 'XXXX', :userName => 'xxxxxx', :password => 'xxxxx'}
)
puts response
Ошибка, которую я получаю, это:
savon/response.rb:85:in `raise_soap_and_http_errors!': (SOAP-
ENV:Server) Exception executing request (Savon::SOAPFault)
from C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/savon-2.4.0/lib/savon/response.rb:14:in `initialize'
from C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/savon-2.4.0/lib/savon/operation.rb:64:in `new'
from C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/savon-2.4.0/lib/savon/operation.rb:64:in `create_response'
from C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/savon-2.4.0/lib/savon/operation.rb:55:in `call'
from C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/savon-2.4.0/lib/savon/client.rb:36:in `call'
from xxx_soap.rb:15:in `<main>'
Я использую Ruby 1.9, у кого-нибудь есть идеи о том, что заставит это работать?
редактировать: переменная wsdl_path, используемая для создания клиента Savon, работает. Я могу создать клиента, а также выполнить client.operations и успешно вернуть операции из службы SOAP. Сбой только в запросе.
редактировать: после добавления полезного кода ведения журнала ниже я возвращаю это:
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:common="urn:xxx-com:cloud:common"
xmlns:finsvc="urn:xxx-com:cloud:finsvc"
xmlns:finsvc-13-6-0="urn:xxx-com:cloud:finsvc:13.6.0">
<SOAP-ENV:Body SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Fault>
<faultcode>SOAP-ENV:Server</faultcode>
<faultstring>Exception executing request</faultstring>
<detail>
<operationResult>
<errorCode>101</errorCode>
<errorMessage>SOAP error 44 (SOAP 1.1 fault: SOAP-ENV:Client [no subcode] "Validation constraint violation: occurrence v
iolation in element 'userName'" Detail: [no detail] )</errorMessage>
</operationResult>
</detail>
</SOAP-ENV:Fault>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Независимо от того, в каком порядке я ввожу параметры или использую ли я camelcase или нет, первый параметр, указанный в сообщении, выдает указанную выше ошибку.
Ответ №1:
Включите ведение журнала с помощью
client = Savon.client(
...
log: true,
loglevel: :debug,
pretty_print_xml: true)
и поделитесь выводом, если вы не можете найти проблему.
Если проблема все еще существует, вам следует пойти стандартным путем:
- Получить SoapUI
- создайте действительный вызов, который вы можете успешно выполнить
- исходя из этого — напишите скрипт Ruby (не Ruby on Rails !!) который создает действительный запрос
- интегрируйте этот код в свои Rails (или любой другой проект).
Комментарии:
1. Спасибо, мне было трудно выводить на консоль, что происходит. Я добавил предложенный вами код, и похоже, что запрос каким-то образом не выполняется по самим параметрам _ Я добавил вывод ошибки в свой вопрос…
Ответ №2:
Итак, все это оказалось проблемами в документе wsdl, где обязательные поля не были указаны как таковые, но ответ от службы этого не показал.
Ответ №3:
wsdl_path
должен быть полный URL, например http://domain.name/.../soap.wsdl
.
Комментарии:
1. Я почти уверен, что ваше утверждение здесь неверно. wsdl_path также может указывать на локальный файл, что он и делает здесь. Как я уже сказал, файл wsdl, на который ссылается эта переменная, работает в SOAP UI, а клиентское соединение с использованием переменной wsdl работает, так что, например, я могу создать клиента, а затем использовать client.operations и получить список операций из службы SOAP.
2. Да, вы правы. Полученная вами ошибка — это SoapFault, а не ошибка HTTP.