Просмотр XML-запроса Savon без отправки на сервер

#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, поэтому он не сможет воспроизвести каждый тип запросов, которые вы делаете, но на данный момент он отвечает моим потребностям.