无法在使用 Savon 的 SOAP 调用中指定 header

Can't specify header in SOAP call using Savon

当调用 API 检索 post 包裹的标签时,我对使用 ruby.

设置 SOAP 调用的难度感到沮丧

我知道以下内容适用于沙盒环境:

这是应该的调用

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Header>
    <Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://postnl.nl/cif/services/BarcodeWebService/IBarcodeWebService/GenerateBarcode</Action>
    <Security xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
      <wsse:UsernameToken xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
        <wsse:Username>devc_!R4xc8p9</wsse:Username>
        <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">098fd559930983af31ef6630a0bb0c1974156561</wsse:Password>
      </wsse:UsernameToken>
    </Security>
  </s:Header>
  <s:Body>
    <GenerateBarcode xmlns:d6p1="http://postnl.nl/cif/domain/BarcodeWebService/" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://postnl.nl/cif/services/BarcodeWebService/">
      <d6p1:Message>
        <d6p1:MessageID>5</d6p1:MessageID>
        <d6p1:MessageTimeStamp>28-06-2017 14:15:41</d6p1:MessageTimeStamp>
      </d6p1:Message>
      <d6p1:Customer>
        <d6p1:CustomerCode>DEVC</d6p1:CustomerCode>
        <d6p1:CustomerNumber>11223344</d6p1:CustomerNumber>
      </d6p1:Customer>
      <d6p1:Barcode>
        <d6p1:Type>3S</d6p1:Type>
        <d6p1:Range>DEVC</d6p1:Range>
        <d6p1:Serie>1000000-2000000</d6p1:Serie>
      </d6p1:Barcode>
    </GenerateBarcode>
  </s:Body>
</s:Envelope>

编辑

据我所知,我使用 build_request 来检查我的请求的外观。它实际上看起来像这样:

<?xml version="1.0" encoding="UTF-8"?>
  <env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:wsdl="http://tempuri.org/" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
  <env:Header>
    <Username>devc_!R4xc8p9</Username
    <Password>098fd559930983af31ef6630a0bb0c1974156561</Password>
  </env:Header>
  <env:Body><wsdl:GenerateBarcode><CustomerCode>DEVC</CustomerCode>
    <CustomerNumber>11223344</CustomerNumber>
    <Type>3S</Type>
    <Range>DEVC</Range>
    <Serie>1000000-2000000</Serie>
</wsdl:GenerateBarcode>
</env:Body>
</env:Envelope>

与上面的 xml 相比,很明显东西不对了。如何处理嵌套?

这是我自己搭建的时候:

@client = Savon.client(
                :convert_request_keys_to => :camelcase,
                :raise_errors => false,
                :pretty_print_xml => true,
                :wsdl => 'https://testservice.postnl.com/CIF_SB/BarcodeWebService/1_1/?wsdl',
                :headers => {
                  'Username' => 'devc_!R4xc8p9',
                  'Password' => '098fd559930983af31ef6630a0bb0c1974156561'
                })

      @response = @client.call(:generate_barcode) do
        soap_header "Username" => 'devc_!R4xc8p9',
                    "Password" => '098fd559930983af31ef6630a0bb0c1974156561'
        message customer_code:   'DEVC',
                customer_number: 11223344,
                type:            '3S',
                range:           'DEVC',
                serie:           '1000000-2000000'
      end

我知道我的连接有效,但也会回来:

{:fault=>{:faultcode=>"s:CIF Framework Message Interceptor",
   :faultstring=>"Check CIFException in the detail section", :detail=>
     {:cif_exception=>{:errors=>{:exception_data=>{:description=>nil,
    :error_msg=>"Username/password is not specified.",
    :error_number=>"3"}},
  :@xmlns=>"http://postnl.nl/cif/services/common/", 
  :"@xmlns:i"=>"http://www.w3.org/2001/XMLSchema-instance"}}}}

所以我的 header 东西已经出错了。 Username/password 未指定。我尝试了几种组合,但我不明白为什么。

更新

@client = Savon.client(
        :env_namespace => :s,
        # :namespace_identifier => :none, # :none doesn't work... gets interpreted literary. Out-commeting gives wsdl:GenerateBarcode 
        :convert_request_keys_to => :camelcase,
        :raise_errors => false,
        :pretty_print_xml => true,
        :endpoint => 'https://testservice.postnl.com/CIF_SB/BarcodeWebService/1_1/BarcodeWebService.svc',
        :wsdl => 'https://testservice.postnl.com/CIF_SB/BarcodeWebService/1_1/?wsdl')

      soap_header = {
                      "Security" => {
                        "UsernameToken" => {
                          "Username" => 'devc_!R4xc8p9',
                          "Password" => '098fd559930983af31ef6630a0bb0c1974156561'
                        }
                      }
                    }


      message = {
                    "d6p1:Customer" => {
                      "d6p1:CustomerCode"    => 'DEVC',
                      "d6p1:CustomerNumber"  => 11223344
                    },
                    "d6p1:Barcode" => {
                      "d6p1:Type" => '3S',
                      "d6p1:Range" => 'DEVC',
                      "d6p1:Serie" => '1000000-2000000'
                    }
                }



      @request = @client.build_request(:generate_barcode) do
        soap_header soap_header
        message message
      end

      @response = @client.call(:generate_barcode) do
        soap_header soap_header
        message message

构建以下请求:

<?xml version="1.0" encoding="UTF-8"?>
  <s:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:s="http://tempuri.org/" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Header>
    <Security>
      <UsernameToken>
        <Username>devc_!R4xc8p9</Username
        <Password>098fd559930983af31ef6630a0bb0c1974156561</Password>
      </UsernameToken>
    </Security>
  </s:Header>
  <s:Body>
    <wsdl:GenerateBarcode>
      <d6p1:Customer>
        <d6p1:CustomerCode>DEVC</d6p1:CustomerCode
        <d6p1:CustomerNumber>11223344</d6p1:CustomerNumber>
      </d6p1:Customer>
      <d6p1:Barcode>
        <d6p1:Type>3S</d6p1:Type>
        <d6p1:Range>DEVC</d6p1:Range>
        <d6p1:Serie>1000000-2000000</d6p1:Serie>
      </d6p1:Barcode></s:GenerateBarcode>
</s:Body>

到目前为止,我在直接在 soap_header 哈希中添加 wsse: 命名空间时遇到错误。

编辑 2

<?xml version="1.0" encoding="UTF-8"?>
<s:Envelope 
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:wsdl="http://tempuri.org/"
  xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Header>
    <Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://postnl.nl/cif/services/BarcodeWebService/IBarcodeWebService/GenerateBarcode
    </Action>
    <Security xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
      <UsernameToken>
        <Username>devc_!R4xc8p9</Username>
        <Password>xxxxxxxx</Password>
      </UsernameToken>
    </Security>
  </s:Header>
  <s:Body>
    <wsdl:GenerateBarcode>
      <d6p1:Customer>
        <d6p1:CustomerCode>DEVC</d6p1:CustomerCode>
        <d6p1:CustomerNumber>11223344</d6p1:CustomerNumber>
      </d6p1:Customer>
      <d6p1:Barcode>
        <d6p1:Type>3S</d6p1:Type>
        <d6p1:Range>DEVC</d6p1:Range>
        <d6p1:Serie>1000000-2000000</d6p1:Serie>
      </d6p1:Barcode>
    </wsdl:GenerateBarcode>
  </s:Body>
</s:Envelope>

与我的 相比应该是 调用似乎我的 <s:envelope ...> 标签有太多信息。

我可能会对此提出后续问题。

编辑 3

我在

重新开始

消息散列,应该以与调用期望的方式相同的方式嵌套,例如

@client = Savon.client(
  :convert_request_keys_to => :camelcase,
  :raise_errors => false,
  :pretty_print_xml => true,
  :wsdl => 'https://testservice.postnl.com/CIF_SB/BarcodeWebService/1_1/?wsdl',
  :headers => {
    'Username' => 'devc_!R4xc8p9',
    'Password' => '098fd559930983af31ef6630a0bb0c1974156561'
})

@response = @client.call(:generate_barcode) do
  soap_header "Security" => {
                "UsernameToken" => {
                  "Username" => 'devc_!R4xc8p9',
                  "Password" => '098fd559930983af31ef6630a0bb0c1974156561'
                }
              }
  message "GenerateBarcode" => {
            "Message" => {
              "MessageID"   => 5, #might be different
              "MessageTime" => Time.now, #might be different depending on use case
            },
            "Customer" => {
              "CustomerCode"   => 'DEVC',
              "CustomerNumber" => 11223344
            },
            "Barcode" => {
              "Type"  => '3S',
              "Range" => 'DEVC',
              "Serie" => '1000000-2000000'
            }
          }
  end

编辑

引用 this page 看起来您可以像这样添加操作标签和元素

 'Action' =>  "http://postnl.nl/cif/services/BarcodeWebService/IBarcodeWebService/GenerateBarcode",
 :attributes! => {
   "s:mustUnderstand" => "1",
   "xmlns" => "http://schemas.microsoft.com/ws/2005/05/addressing/none"
 }

引用 this page 看起来你可以直接设置命名空间 "wsse:UsernameToken" 而不是 "UsernameToken"

结果如下

@client = Savon.client(
  :convert_request_keys_to => :camelcase,
  :raise_errors => false,
  :pretty_print_xml => true,
  :wsdl => 'https://testservice.postnl.com/CIF_SB/BarcodeWebService/1_1/?wsdl',
  :headers => {
    'Username' => 'devc_!R4xc8p9',
    'Password' => '098fd559930983af31ef6630a0bb0c1974156561'
})

@response = @client.call(:generate_barcode) do
  soap_header "Security" => {
                "wsse:UsernameToken" => {
                  "wsse:Username" => 'devc_!R4xc8p9',
                  "wsse:Password" => '098fd559930983af31ef6630a0bb0c1974156561'
                }     
              "Action" =>  "http://postnl.nl/cif/services/BarcodeWebService/IBarcodeWebService/GenerateBarcode",
              :attributes! => {
                "s:mustUnderstand" => "1",
                "xmlns" => "http://schemas.microsoft.com/ws/2005/05/addressing/none"
              }
            }
  message "GenerateBarcode" => {
            "Message" => {
              "MessageID"   => 5, #might be different
              "MessageTime" => Time.now, #might be different depending on use case
            },
            "Customer" => {
              "CustomerCode"   => 'DEVC',
              "CustomerNumber" => 11223344
            },
            "Barcode" => {
              "Type"  => '3S',
              "Range" => 'DEVC',
              "Serie" => '1000000-2000000'
            }
          }
  end