无法使用Savon在SOAP调用中指定标头

时间:2017-06-28 13:56:33

标签: ruby-on-rails savon

当调用API检索邮政包裹的标签时,我对使用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>

修改

作为sugested,我使用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"}}}}

所以我的标题已经出错了。未指定用户名/密码。我尝试了几种组合,但我不明白为什么。

更新

@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>

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

编辑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

我在Complex SOAP call in Ruby on Rails using Savon gets weird around the envelope and main operation

重新开始

1 个答案:

答案 0 :(得分:1)

Message hash应该以与调用期望

类似的方式嵌套
@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