简体   繁体   English

在Ruby中使用Savon时的Soap Request格式

[英]Soap Request Format when using Savon in ruby

I am dealing with a soap api which offers the following as an example of how the request XML should look: 我正在处理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>

Below is the code I am using to attempt this request in rails (covering up my access token for privacy's sake): 下面是我用来在Rails中尝试此请求的代码(出于隐私的考虑而收集我的访问令牌):

require 'savon'
client = Savon.client({ wsdl: "http://wsportal.aaacooper.com:8188/wsGenRateEstimate.wsdl" })
# this part is to check what the XML I am sending will look like
request = client.build_request(:ws_gen_rate_estimate, message: { Token: "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", OriginCity: "Birmingham", OriginState: "AL", OriginZip: "35222", OriginCountryCode: "USA", DestinationCity: "New Orleans", DestinationState: "LA", DestinationZip: "70122", DestinCountryCode: "USA", CustomerNumber: "000971733", WhoAmI: "S", PrePaidCollect: "" })
# This will actually send the xml to the server api
response = client.call(:ws_gen_rate_estimate, message: { Token: "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", OriginCity: "Birmingham", OriginState: "AL", OriginZip: "35222", OriginCountryCode: "USA", DestinationCity: "New Orleans", DestinationState: "LA", DestinationZip: "70122", DestinCountryCode: "USA", CustomerNumber: "000971733", WhoAmI: "S", PrePaidCollect: "" })
render json: {
  "this is a": "test",
  "client_request": request.body,
  "client_response": response.body,
}, status: :ok

The response to this request has an "error_message" saying my Token is invalid, however I know I have a valid token, and I know that it is pasted in full in the code there. 对此请求的响应带有“ error_message”,表示我的令牌无效,但是我知道我有一个有效的令牌,并且知道该令牌已完全粘贴在该代码中。 Here is what the XML looks like being sent to the server: 这是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>

The tag names and namespaces are different than the example asks for. 标签名称和名称空间与示例所要求的不同。 Could this cause the API to not find the token? 这会导致API找不到令牌吗? If so, does the savon gem provide options to change tag names or attributes? 如果是这样,savon gem是否提供更改标签名称或属性的选项?

The node that your Savon is producing is called token whereas the service is expecting to receive Token (with capital T ). 您的Savon正在生产的节点称为token而服务期望接收Token (大写T )。 As you can see, all the nodes have the same problem: they are sent with the initial letter in lowercase and they are expected to be received in uppercase. 如您所见,所有节点都存在相同的问题:它们以首字母小写发送,并且期望以大写形式接收。

Savon by default will convert keys to lowerCamelcase. Savon 默认会将键转换为lowerCamelcase。 You can change this behavior in the global convert_request_keys_to . 您可以在全局convert_request_keys_to更改此行为。

The options to this global are :camelcase , :lower_camelcase , :upcase and :none . 全局选项包括:camelcase:lower_camelcase:upcase:none In your problem, you should use :camelcase . 在您的问题中,您应该使用:camelcase

require 'savon'
client = Savon.client(
  wsdl: "http://wsportal.aaacooper.com:8188/wsGenRateEstimate.wsdl",
  convert_request_keys_to: :camelcase
)

This way, you can send your request as: 这样,您可以将请求发送为:

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

And the keys will be converted to its corresponding camelcase. 并将密钥转换为相应的驼峰式密码。 Note that you can write them in snakecase and will be transformed correctly. 请注意,您可以将它们snakecase ,并将正确转换。

This might help as it worked for me following railscasts 这可能会有所帮助,因为它在railscasts对我railscasts

Gyoku.convert_symbols_to :camelcase

For example: 例如:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM