使用Savon连接到Web服务

时间:2014-03-20 16:19:46

标签: ruby-on-rails ruby jruby savon

我正在尝试使用Savon从Ruby连接到Web服务 - 它是一个基于SOAP的Web服务。它还需要一个我拥有密钥的x509证书,但我试图在一分钟内绕过这个,只是为了让ssl_verify_mode设置为无

  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)

我已经能够在.NET中生成我的WSDL类并从c#客户端应用程序中点击Web服务。

我从客户端调用GetInformation的C#位于

之下
                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>

如果我查看soap UI并单击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>

1 个答案:

答案 0 :(得分:0)

我会避免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