Формат запроса на мыло при использовании Savon в ruby - PullRequest
0 голосов
/ 06 ноября 2018

Я имею дело с мыльным 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>

Ниже приведен код, который я использую для выполнения этого запроса в рельсах (прикрывая мой токен доступа в целях конфиденциальности):

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

В ответе на этот запрос есть «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>

Имена тегов и пространства имен отличаются от того, который запрашивается в примере. Может ли это привести к тому, что API не найдет токен? Если да, то предоставляет ли savon gem опции для изменения имен тегов или атрибутов?

Ответы [ 2 ]

0 голосов
/ 09 мая 2019

Это может помочь, так как это работает для меня после railscasts

Gyoku.convert_symbols_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
0 голосов
/ 14 ноября 2018

Узел, который создает ваш Savon, называется token, тогда как служба ожидает получения Token (с капиталом T). Как видите, у всех узлов одна и та же проблема: они отправляются с начальным письмом в нижнем регистре, и ожидается, что они будут получены в верхнем регистре.

Savon по умолчанию преобразует ключи в нижний регистр. Вы можете изменить это поведение в глобальном convert_request_keys_to.

Варианты этого глобального: :camelcase, :lower_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" })

И ключи будут преобразованы в соответствующий верблюд. Обратите внимание, что вы можете записать их в snakecase и будут преобразованы правильно.

...