【问题标题】:Trying to build SOAP Request with Savon?尝试使用 Savon 构建 SOAP 请求?
【发布时间】:2014-03-24 10:34:56
【问题描述】:

我正在尝试从 Ruby on Rails 访问 SOAP 服务 - 从 SOAP UI 我可以很好地访问它,请求 XML 如下:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/" xmlns:mun="http://schemas.datacontract.org/2004/07/MyExternalService.Map" xmlns:mun1="http://schemas.datacontract.org/2004/07/MyExternalService.Common.Map">
   <soapenv:Header/>
   <soapenv:Body>
      <tem:GetInformationsForCoordinates>
         <!--Optional:-->
         <tem:coordReq>
            <!--Optional:-->
            <mun:Coordinates>
               <!--Zero or more repetitions:-->
               <mun:Coordinate>
                  <!--Optional:-->
                  <mun:Id>1</mun:Id>
                  <!--Optional:-->
                  <mun:QualityIndex>90</mun:QualityIndex>
                  <!--Optional:-->
                  <mun:X>-110.5322</mun:X>
                  <!--Optional:-->
                  <mun:Y>35.2108</mun:Y>
               </mun:Coordinate>
            </mun:Coordinates>
         </tem:coordReq>
         <!--Optional:-->
         <tem:analysisTypes>
            <!--Zero or more repetitions:-->
            <mun:AnalysisType>Additional</mun:AnalysisType>
         </tem:analysisTypes>
      </tem:GetInformationsForCoordinates>
   </soapenv:Body>
</soapenv:Envelope>

如果我将确切的 XML 复制到带有 request = %q(XML STRING) 的 Ruby 字符串到 savon 中并使用该方法,然后在 Savon 中调用以下内容:

response = client.call(:get_info, xml: request)

它按预期工作,我得到了回应 - 但实际上我只想将参数传递给 Savon。到目前为止,我已经尝试了以下方法:

  coordinate = { Id: '1', X: -110.5322, Y: 35.2108, QualityIndex: 90 }
  coordinates = {Coordinates: [coordinate] }
  coordinateReq = {coordReq: {coordinates: coordinates} }
  response = client.call(:get_informations_for_coordinates, message: coordinateReq)

这失败了,如果我查看我发送的 XML,它如下所示:

<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>
      <coordReq>
        <coordinates>
          <coordinates>
            <Id>1</Id>
            <X>-110.5322</X>
            <Y>35.2108</Y>
            <QualityIndex>90</QualityIndex>
          </coordinates>
        </coordinates>
      </coordReq>
    </tns:GetInformationsForCoordinates>
  </env:Body>
</env:Envelope>

与从 SOAP UI 发送的内容相比,我缺少 xmlns:mum 命名空间 - 无论如何我可以将它添加到我的请求中,以便将其添加到每个参数,即 X、Y QualityIndex - 也是类似的 tem我的 Savon 调用中的 tns 添加到 SOAPUI 中的 coordReq 但不在我的 Savon 调用中 - 无论如何我可以添加它吗?

我在确定如何构建我的请求的 analysisTypes 和 AnalysisType 部分时也遇到了一些困难?

【问题讨论】:

    标签: ruby-on-rails ruby soap savon


    【解决方案1】:

    来自documentation

    命名空间

    如果您不将命名空间传递给 Savon::Client#request,Savon 将 为您注册目标命名空间 (“xmlns:wsdl”)。如果你做了 传递一个命名空间,Savon 将使用它而不是默认的。为了 示例:

    client.request :v1, :get_user
    
    <env:Envelope
        xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
        xmlns:xsd="http://www.w3.org/2001/XMLSchema"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:v1="http://v1.example.com">
      <env:Body>
        <v1:GetUser>
      </env:Body>
    </env:Envelope>
    

    您始终可以设置命名空间或覆盖 Savon 设置的命名空间。 命名空间存储为简单的哈希。

    # setting a new namespace
    soap.namespaces["xmlns:g2"] = "http://g2.example.com"
    
    # overwriting the "xmlns:wsdl" namespace
    soap.namespaces["xmlns:wsdl"] = "http://ns.example.com"
    

    显然,对于Savon 2,设置多个命名空间是impossible

    我发现(目前)无法设置多个命名空间 Savon 的第 2 版。

    现在我在 Savon 版本 1 上迁移我的应用程序并且它工作了 =)

    【讨论】:

    • 对不起,我应该说我使用的是 Savon 版本 2 - 我已经添加了这里显示的命名空间 - savonrb.com/version2/globals.html 但它添加了多个命名空间,我似乎无法在我需要的地方开始工作在我的 SOAP UI 请求中显示了一些参数和 mun 其他参数
    • 关于我的问题的另一部分的任何想法 - 即 - 如何建立分析响应和类型到我传递给消息的请求中:
    • 编辑了我的答案。我相信你应该为第二部分提出一个新问题。
    【解决方案2】:

    要使用多个命名空间,您可以在客户端定义中添加以下类型的代码

    ...
    :namespaces => {
        "xmlns:v2" => "http://v2.example.com",
        "xmlns:v1" => "http://v1.example.com" },
    ...
    

    【讨论】:

    • 这适用于 Savon 版本 2 Steffen - 我如何确定不同参数选择哪个命名空间?
    • 实际上刚刚找到以下链接 - coderwall.com/p/erwfda - 所以会按照它的建议尝试
    • 是的,它应该适用于 v2。只需明确限定您的密钥,例如'v1:Getuser','v2:whatever'
    猜你喜欢
    • 1970-01-01
    • 2012-07-30
    • 1970-01-01
    • 1970-01-01
    • 2012-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多