Подключение к веб-сервису с Savon

Я пытаюсь подключиться к веб-сервису из Ruby с помощью Savon - это веб-сервис на основе SOAP. Для этого также требуется сертификат x509, для которого у меня есть ключи, но я пытаюсь обойти это в минуту, просто чтобы он работал с ssl_verify_mode, для которого установлено значение none.

  client = Savon.client(wsdl: WSDL_URL,
                        log: true, # set to true to switch on logging
                        log_level: :debug,
                        convert_request_keys_to: :camelcase,
                        pretty_print_xml: true,
                        ssl_verify_mode: :none)

Мне удалось сгенерировать классы WSDL в .NET и использовать веб-сервис из клиентского приложения С#.

Мой С# для вызова GetInformation от клиента ниже

                var analysisTypes = new AnalysisType[4];
                analysisTypes[0] = AnalysisType.A;
                analysisTypes[1] = AnalysisType.B;
                analysisTypes[2] = AnalysisType.C;
                analysisTypes[3] = AnalysisType.D;

                var coord1 = new Coordinate {
                                       Id = i.ToString(),
                                       X = -110.5322,
                                       Y = 35.2108, QualityIndex = 90 };

                string ticketId = serviceClient.GetInformationsForCoordinates(
                                                           coord1, analysisTypes);

Однако я новичок в Ruby, и мне трудно заставить то же самое, сгенерированное ниже, передать Savon - пока у меня есть следующее:

  coordinate = { Id: '1', X: -110.5322, Y: 35.2108, QualityIndex: 90 }
  ticket_id = client.call(:get_informations_for_coordinates,
                          message: coordinate)

  print ticket_id

Это не удается - я вижу сообщение SOAP, которое оно отправляет ниже:

<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
              xmlns:tns="http://tempuri.org/"
              xmlns:xsd="http://www.w3.org/2001/XMLSchema"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <env:Body>
    <tns:GetInformationsForCoordinates>
      <Id>1</Id>
      <X>-110.5322</X>
      <Y>35.2108</Y>
      <QualityIndex>90</QualityIndex>
    </tns:GetInformationsForCoordinates>
  </env:Body>
</env:Envelope>

Если я посмотрю на мыльный интерфейс и нажму на GetInformationsForCoordinates, я увижу, как мне следует создать сообщение SOAP - как мне лучше всего создать этот тип сообщения в Ruby - я должен передать все это как сообщение и изменить переменная координаты должна быть сообщением?

<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"
               xmlns:tem="http://tempuri.org/"
               xmlns:mun="http://WebService I want to hit"
               xmlns:mun1="http://WebService I want to Hit">
   <soap:Header/>
   <soap:Body>
      <tem:GetInformationsForCoordinates>
         <!--Optional:-->
         <tem:coordReq>
            <!--Optional:-->
            <mun:Basemap>?</mun:Basemap>
            <!--Optional:-->
            <mun:GenerateReport>?</mun:GenerateReport>
            <!--Optional:-->
            <mun:MapsForReport>
               <!--Zero or more repetitions:-->
               <mun1:HMap>?</mun1:HMap>
            </mun:MapsForReport>
            <!--Optional:-->
            <mun:PortName>?</mun:PortName>
            <!--Optional:-->
            <mun:Coordinates>
               <!--Zero or more repetitions:-->
               <mun:Coordinate>
                  <!--Optional:-->
                  <mun:Id>?</mun:Id>
                  <!--Optional:-->
                  <mun:QualityIndex>?</mun:QualityIndex>
                  <!--Optional:-->
                  <mun:X>?</mun:X>
                  <!--Optional:-->
                  <mun:Y>?</mun:Y>
               </mun:Coordinate>
            </mun:Coordinates>
         </tem:coordReq>
         <!--Optional:-->
         <tem:analysisTypes>
            <!--Zero or more repetitions:-->
            <mun:AnalysisType>?</mun:AnalysisType>
         </tem:analysisTypes>
      </tem:GetInformationsForCoordinates>
   </soap:Body>
</soap:Envelope>

person Ctrl_Alt_Defeat    schedule 20.03.2014    source источник


Ответы (1)


Я бы избегал сложных структур в сообщении SOAP. Это означало бы, что я бы не использовал массив в качестве параметра. Я даже не уверен, поддерживается ли это вообще.

Вы также можете добавить префикс к элементам в своем сообщении, например:

coordinate = { 'tns:Id' => '1',
               'tns:X' => -110.5322,
               'tns:Y' => 35.2108, 
               'tns:QualityIndex' => 90 }

или в зависимости от того, какое пространство имен определяет эти элементы.

Чтобы создать список параметров, нужно построить хеш для сообщения. Полный вызов будет выглядеть так (это неправильный фрагмент кода, но он должен дать вам правильное направление):

require 'pp'
require 'savon'

client = Savon.client(wsdl: WSDL_URL,
                    log: true, # set to true to switch on logging
                    log_level: :debug,
                    convert_request_keys_to: :camelcase,
                    pretty_print_xml: true,
                    ssl_verify_mode: :none)
rc = client.call(:get_informations_for_coordinates,
                  message: {
                     coordinates => { 'tns:Id' => '1',
                                      'tns:X' => -110.5322,
                                      'tns:Y' => 35.2108, 
                                      'tns:QualityIndex' => 90 },
                     analysis_types => {
                                      'tns:type0' => 'A',
                                      'tns:type1' => 'B'
                                    }
                  }
                 )
pp rc.to_hash
person Steffen Roller    schedule 20.03.2014
comment
Привет, Стефан, и поэтому мой вызов C # также принимал параметры - координаты и типы анализа - в Ruby, когда я вызываю client.call (: get_informations_for_coordinates, - как я должен передать как координату, так и типы анализа? - person Ctrl_Alt_Defeat; 20.03.2014
comment
@KOL Пожалуйста, перепроверьте мой ответ. Я изменил, чтобы отразить ваш вопрос в вашем комментарии. - person Steffen Roller; 21.03.2014