Ruby on rails 在ruby中使用Savon时的Soap请求格式

Ruby on rails 在ruby中使用Savon时的Soap请求格式,ruby-on-rails,xml,soap,savon,Ruby On Rails,Xml,Soap,Savon,我正在处理一个soap api,它提供以下内容作为请求XML的外观示例: <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsg="http://tempuri.org/wsGenRateEstimate/"> <soap:Header/> <soap:Bo

我正在处理一个soap api,它提供以下内容作为请求XML的外观示例:

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsg="http://tempuri.org/wsGenRateEstimate/">
   <soap:Header/>
   <soap:Body>
      <RateEstimateRequestVO>
         <Token>7e2c61c4-8b4c-4d8b-b47f-ed033c6f4307</Token>
         <CustomerNumber>1</CustomerNumber>
         <OriginCity>Dothan</OriginCity>
         <OriginState>AL</OriginState>
         <OriginZip>36303</OriginZip>
         <OriginCountryCode>USA</OriginCountryCode>
         <DestinationCity>Atlanta</DestinationCity>
         <DestinationState>GA</DestinationState>
         <DestinationZip>30303</DestinationZip>
         <DestinCountryCode>USA</DestinCountryCode>
         <WhoAmI>S</WhoAmI>
         <BillDate>050415</BillDate>
         <CODAmount></CODAmount>
         <CODPayType></CODPayType>
         <CODFeePaidBy></CODFeePaidBy>
         <FullCoverage>Y</FullCoverage>
         <FullCoverageAmount>32545</FullCoverageAmount>
         <PrePaidCollect></PrePaidCollect>
         <TotalPalletCount></TotalPalletCount>
         <!--Zero or more repetitions:-->
         <AccLine>
            <AccCode></AccCode>
         </AccLine>
         <!--Zero or more repetitions:-->
         <RateEstimateRequestLine>
            <Weight>122</Weight>
            <Class>70</Class>
            <HandlingUnits></HandlingUnits>
            <HandlingUnitType></HandlingUnitType>
            <Hazmat></Hazmat>
            <CubeU></CubeU>
            <Length></Length>
            <Height></Height>
            <Width></Width>
         </RateEstimateRequestLine>
      </RateEstimateRequestVO>
   </soap:Body>
</soap:Envelope>
对此请求的响应有一条“error_message”,表示我的令牌无效,但我知道我有一个有效的令牌,并且我知道它已完全粘贴在那里的代码中。以下是发送到服务器的XML的外观:

<?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:tns=\"http://tempuri.org/wsGenRateEstimate/\" xmlns:env=\"http://schemas.xmlsoap.org/soap/envelope/\">
        <env:Body>
           <tns:RateEstimateRequestVO>
              <token>XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX</token>
              <originCity>Birmingham</originCity>
              <originState>AL</originState>
              <originZip>35222</originZip>
              <originCountryCode>USA</originCountryCode>
              <destinationCity>New Orleans</destinationCity>
              <destinationState>LA</destinationState>
              <destinationZip>70122</destinationZip>
              <destinCountryCode>USA</destinCountryCode>
              <customerNumber>000971733</customerNumber>
              <whoAmI>S</whoAmI>
              <prePaidCollect></prePaidCollect>
            </tns:RateEstimateRequestVO>
        </env:Body>
     </env:Envelope>

XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX
伯明翰
艾尔
35222
美国
新奥尔良
洛杉矶
70122
美国
000971733
s

标记名和名称空间与示例要求的不同。这是否会导致API找不到令牌?如果是这样,savon gem是否提供更改标记名称或属性的选项?

您的savon正在生成的节点称为
token
,而服务希望接收
token
(大写
T
)。正如您所看到的,所有节点都有相同的问题:它们以小写字母发送,并且预期以大写字母接收

Savon将钥匙转换为lowerCamelcase。您可以在全局
将请求密钥转换为
中更改此行为

此全局设置的选项有
:camelcase
:lower\u camelcase
:upcase
:none
。 在您的问题中,您应该使用
:camelcase

require 'savon'
client = Savon.client(
  wsdl: "http://wsportal.aaacooper.com:8188/wsGenRateEstimate.wsdl",
  convert_request_keys_to: :camelcase
)
这样,您可以通过以下方式发送请求:

request = client.build_request(:ws_gen_rate_estimate, message: { token: "XXXXX", origin_city: "Birmingham" })

并且密钥将转换为相应的camelcase。请注意,您可以在
snakecase
中编写它们,并且可以正确地进行转换。

这可能会有所帮助,因为这对我遵循
railscasts

Gyoku.convert\u symbols\u to:camelcase

例如:

def initialize(test)
  Gyoku.convert_symbols_to :camelcase
  client = Savon::Client.new("wsdl_link")
  response = client.request :web, :get_actions, body: { "test" => test }
  if response.success?
  // enter code
  end
end

是的,这就是reazon,在初始化
Savon.client
时尝试使用
名称空间:“我的名称空间/url”
。如果仍不起作用,请尝试添加
元素\u表单\u默认值::限定值
。我几个月前就遇到了这个问题,我不确定哪种解决方案解决了这个问题。我看到您生成的请求中的节点是
token
,而在描述中似乎是
token
,我认为这可以通过
Savon.client
初始化中的
convert\u request\u keys\u to::camelcase
解决。谢谢Byrdmanuel。camelcase选项修复了它!很高兴它成功了!我将把它作为一个答案来写,以帮助更多的人在同一个问题上。如果你发布它,我将接受它作为答案。再次感谢!
def initialize(test)
  Gyoku.convert_symbols_to :camelcase
  client = Savon::Client.new("wsdl_link")
  response = client.request :web, :get_actions, body: { "test" => test }
  if response.success?
  // enter code
  end
end