#ruby #xml #soap #savon #httpi
#ruby #xml #soap #savon #httpi
Вопрос:
Я использую драгоценный камень Savon для выполнения запроса SOAP, используя код, аналогичный приведенному ниже. Это работает, но я хотел бы просмотреть / захватить XML-запрос, фактически не вызывая их сервер. Теперь я могу просмотреть его после выполнения запроса, вставив строку отладчика после запроса и проверив переменную клиента.
Кто-нибудь знает способ просмотра XML-запроса без фактического выполнения запроса? Я хочу иметь возможность проверять XML на соответствие схеме, используя Cucumber или Rspec.
client = Savon::Client.new do |wsdl, http|
wsdl.document = "http://fakesite.org/fake.asmx?wsdl"
end
client.request(:testpostdata, :xmlns => "http://fakesite.org/") do
soap.header = { :cAuthentication => {"UserName" => "MyName", "Password" => "MyPassword" } }
soap.body = { :xml_data => to_xml }
end
Ответ №1:
Используя Savon 2, я делаю это следующим образом, пишу метод, который возвращает тело запроса от клиента.
client = Savon::Client.new(....)
в документации об этом не упоминается
def get_request
# list of operations can be found using client.operations
ops = client.operation(:action_name_here)
# build the body of the xml inside the message here
ops.build(message: { id: 42, name: "Test User", age: 20 }).to_s
end
Комментарии:
1. (заменить
to_s
наpretty
выше)
Ответ №2:
Вы можете напрямую с помощью Savon::Client#build_request
метода.
Пример:
request = client.build_request(:some_operation, some_payload)
request.body # Get the request body
request.headers # Get the request headers
Возьмите пик @ https://github.com/savonrb/savon/blob/master/lib/savon/request.rb для получения полного документа.
Комментарии:
1. Это должен быть правильный ответ, поскольку он самый прямой и использует Savon без необходимости изменять какие-либо его части.
Ответ №3:
Я использую Savon 2.11 и могу выполнить это с глобальными значениями в клиенте:
def client
@client ||= Savon.client(soap_version: 2,
wsdl: config.wsdl,
logger: Rails.logger,
log: true)
end
Дополнительная информация о глобальных файлах здесь.
Затем регистратор выдает хост, http-глагол и полный xml («заголовки» и тело) как для запроса, так и для ответа.
Комментарии:
1.также обратите внимание
pretty_print_xml
github.com/savonrb/savon/issues/256
Ответ №4:
Хотя я уверен, что есть лучший способ сделать это, я просто переопределил response.
class Savon::SOAP::Request
def response
pp self.request.headers
puts
puts self.request.body
exit
end
end
Комментарии:
1. Это был дешевый и простой подход для облегчения отладки. Спасибо.
2. а что, если бы я захотел этого, но также отправил запрос на сервер?
Ответ №5:
Они обновили API с момента последнего сообщения. Установите этот параметр в Savon.client: :pretty_print_xml => true. После вашего вызова выполните поиск в журналах запросов SOAP :. Вывод выводится в стандартный вывод. Проверьте историю консоли консоли, если вы тестируете свое соединение с консоли.
Ответ №6:
Savon использует HTTPI для выполнения запросов SOAP. HTTPI — это общий интерфейс поверх различных HTTP-клиентов Ruby. Вероятно, вы могли бы имитировать / заглушать HTTP-запрос, выполняемый Savon через:
HTTPI.expects(:post).with do |http|
SchemaValidation.validate(:get_user, http.body)
end
Пожалуйста, обратите внимание, что я использовал Mocha для подделки запроса SOAP, получения тела HTTP и проверки его на соответствие некоторому методу проверки (псевдокод).
В настоящее время Savon не поддерживает создание запросов без их выполнения. Таким образом, единственным способом проверки запроса было бы его перехват.
Если вам понадобится Savon для поддержки этой функции, пожалуйста, дайте мне знать и откройте заявку на GitHub.
РЕДАКТИРОВАТЬ: Также есть savon_spec, который является небольшим помощником для базового тестирования на основе устройств с Savon.
Комментарии:
1. Спасибо за предложение. Я могу жить без этой функции, просто хотел узнать, возможно ли это.
Ответ №7:
У меня была та же проблема, и я исправил Savon следующим образом:
module Savon
class Client
def get_request_xml operation_name, locals
Savon::Builder.new(operation_name, @wsdl, @globals, locals).pretty
end
end
end
Это создает XML и возвращает его в виде строки без отправки в конечную точку API. Он не принимает аргумент блока так же, как это делает client.call, поэтому он не сможет воспроизвести каждый тип запросов, которые вы делаете, но на данный момент он отвечает моим потребностям.