Ruby on Rails 3.2.11 Savon v2.0.2破坏了我的应用程序



我从1.1.0升级到Savon v2.0.2,它破坏了我的应用程序。我对代码进行了必要的调整,以解释错误回调(Savon::SOAP::Fault到Savon::SOAPFault, Savon::HTTP::Error到Savon::HTTPError等)中的变化,并使用#call vs #request方法。我在跟踪错误时遇到了麻烦,因为现在我得到了堆栈级别太深错误。我把我的上限增加到40000,但没有帮助。我不相信这是我的代码中的循环,因为在v2之前,代码工作得完美无缺。在Savon站点上提供的任何示例或Google搜索的结果都不能与我必须(并且已经)对服务于api的设备进行的XML调用相接近。这是我的客户端配置,XML结构,生成器和XML请求必须做的。我还将包括升级前工作版本中的代码。任何指导都将非常感激。为了安全起见,我模糊了IP、域名等。如果您需要更多的信息,请告诉我。

再次感谢您!

td

两个版本通用:

@api = api.capitalize
service_api_host = '10.10.10.1'
url = "https://#{service_api_host}:8443/#{api}/#{api}?wsdl"
@uname = 'username'
@pwd   = 'password'
@xml1   = "xmlns:soapenv"
@xml2   = "xmlns:ws"
@xmlns1 = "http://schemas.xmlsoap.org/soap/envelope/"
@xmlns2 = "http://ws.#{@api.downcase}.myappliances_domain.com"

典型XML请求:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ws="http://ws.reportingservices.myappliances_domain.com">
  <soapenv:Header xmlns:svsec="http://services.myappliances_domain.com">
    <svsec:username>username</svsec:username>
    <svsec:password>password</svsec:password>
  </soapenv:Header>
  <soapenv:Body>
    <ws:RunTimeSeriesReportRequest>
      <ReportDefinition>MyReportDefinition</ReportDefinition>
      <CsvAttachmentFormat>
        <Compression>None</Compression>
        <Encoding>UTF-8</Encoding>
        <Headers>true</Headers>
      </CsvAttachmentFormat>
      <TimeSeriesReportQuery>
        <QueryFields>
          <QueryField>PeriodStart</QueryField>
          <QueryField>PeriodEnd</QueryField>
          <QueryField>Subscriber.Name</QueryField>
          <QueryField>TotalReceivedBytes</QueryField>
          <QueryField>TotalTransmittedBytes</QueryField>
          <QueryField>TotalBytes</QueryField>
        </QueryFields>
        <QueryFilters>
          <QueryFilter>
            <QueryField>Subscriber.Name</QueryField>
            <Criteria>Equal</Criteria>
            <Value>078DF7</Value>
          </QueryFilter>
        </QueryFilters>
        <MaxRows>0</MaxRows>
        <QueryLocalDataHomeOnly>false</QueryLocalDataHomeOnly>
        <TimeSeries>
          <Start>2012-12-19T06:00:00-07:00</Start>
          <End>2012-12-20T00:00:00-07:00</End>
          <TimeZone>America/Phoenix</TimeZone>
          <Interval>
            <Unit>Hours</Unit>
            <Value>18</Value>
          </Interval>
        </TimeSeries>
      </TimeSeriesReportQuery>
    </ws:RunTimeSeriesReportRequest>
  </soapenv:Body>
</soapenv:Envelope>

为了完整:(创建唯一请求的构建器之一)

xml = Builder::XmlMarkup.new( :indent=>2 )
xml.soapenv:Envelope, :"#{@xml1}"=>"#{@xmlns1}", :"#{@xml2}"=>"#{@xmlns2}" do
  xml.tag!( 'soapenv:Header', :'xmlns:svsec' => 'http://services.myappliances_domain.com' ) do
    xml.tag!( 'svsec:username', @uname )
    xml.tag!( 'svsec:password', @pwd )
  end
  xml.tag!( 'soapenv:Body' ) do
    xml.tag!( "ws:#{request}" ) do
      xml.ReportDefinition('MyReportDefinition')
      xml.CsvAttachmentFormat do
        xml.Compression('None')
        xml.Encoding('UTF-8')
        xml.Headers('true')
      end
      xml.TimeSeriesReportQuery do
        xml.QueryFields do
          xml.QueryField('PeriodStart')
          xml.QueryField('PeriodEnd')
          xml.QueryField('Subscriber.Name')
          xml.QueryField('TotalReceivedBytes')
          xml.QueryField('TotalTransmittedBytes')
          xml.QueryField('TotalBytes')
        end
        xml.QueryFilters do
          xml.QueryFilter do
            xml.QueryField('Subscriber.Name')
            xml.Criteria('Equal')
            xml.Value(sub)
          end
        end
        xml.MaxRows(0)
        xml.QueryLocalDataHomeOnly('false')
        xml.TimeSeries do
          xml.Start("#{start_date}")
          xml.End("#{end_date}")
          xml.TimeZone('America/Phoenix')
          xml.Interval do
            xml.Unit('Hours')
            xml.Value('18')
          end
        end
      end
    end
  end
end

升级前:

客户机def

  @client = Savon::Client.new do |wsdl, http|
    wsdl.document = url
    http.auth.ssl.verify_mode = :none
    http.read_timeout = 120
  end

请求调用

  @response = @client.request "#{params[:reqMethod]}" do
    soap.xml = "#{params[:xml]}"      
  end
升级后

:

客户机def

@client = Savon.client(wsdl: url,
                       encoding: "UTF-8",
                       soap_version: 2,
                       ssl_verify_mode: :none,
                       open_timeout: 5,
                       read_timeout: 120)

请求调用

response = @client.call(:"#{params[:reqMethod]}", xml: params[:xml])

下面是返回Builder结果的典型方法。它是一个字符串,不是一个对象。

从rails控制台:

ruby-1.9.3-p0 :020 >     @uname = 'username'
 => "username" 
ruby-1.9.3-p0 :021 >     @pwd   = 'password'
 => "password" 
ruby-1.9.3-p0 :022 > api = 'SubscriberServices'
 => "SubscriberServices" 
ruby-1.9.3-p0 :023 >     @api = api.capitalize
 => "Subscriberservices" 
ruby-1.9.3-p0 :024 >     @xml1   = "xmlns:soapenv"
 => "xmlns:soapenv" 
ruby-1.9.3-p0 :025 >     @xml2   = "xmlns:ws"
 => "xmlns:ws" 
ruby-1.9.3-p0 :026 >     @xmlns1 = "http://schemas.xmlsoap.org/soap/envelope/"
 => "http://schemas.xmlsoap.org/soap/envelope/" 
ruby-1.9.3-p0 :027 >     @xmlns2 = "http://ws.#{@api.downcase}.myappliance_domain.com"
 => "http://ws.subscriberservices.myappliance_domain.com" 
ruby-1.9.3-p0 :028 >   def getSubAttributes(subscriber)
ruby-1.9.3-p0 :029?>       request = 'LookupSubscriberRequest'
ruby-1.9.3-p0 :030?>       
ruby-1.9.3-p0 :031 >         xml = Builder::XmlMarkup.new( :indent=>2 )
ruby-1.9.3-p0 :032?>       xml.soapenv:Envelope, :"#{@xml1}"=>"#{@xmlns1}", :"#{@xml2}"=>"#{@xmlns2}" do
ruby-1.9.3-p0 :033 >             xml.tag!( 'soapenv:Header', :'xmlns:svsec' => 'http://services.myappliance_domain.com' ) do
ruby-1.9.3-p0 :034 >                 xml.tag!( 'svsec:username', @uname )
ruby-1.9.3-p0 :035?>               xml.tag!( 'svsec:password', @pwd )
ruby-1.9.3-p0 :036?>             end
ruby-1.9.3-p0 :037?>           xml.tag!( 'soapenv:Body' ) do     
ruby-1.9.3-p0 :038 >                 xml.tag!( "ws:#{request}" ) do
ruby-1.9.3-p0 :039 >                     xml.SubscriberKey() do
ruby-1.9.3-p0 :040 >                         xml.SubscriberRealmKey() do
ruby-1.9.3-p0 :041 >                             xml.Name('DEFAULT')
ruby-1.9.3-p0 :042?>                         end
ruby-1.9.3-p0 :043?>                       xml.Name(subscriber)
ruby-1.9.3-p0 :044?>                     end
ruby-1.9.3-p0 :045?>                   xml.ResponseGroups() do
ruby-1.9.3-p0 :046 >                         xml.ResponseGroup('Subscriber.Attributes')
ruby-1.9.3-p0 :047?>                       xml.ResponseGroup('Subscriber.CurrentIpAssignments')
ruby-1.9.3-p0 :048?>                     end
ruby-1.9.3-p0 :049?>                 end
ruby-1.9.3-p0 :050?>             end
ruby-1.9.3-p0 :051?>         end
ruby-1.9.3-p0 :052?>   end
 => nil 
ruby-1.9.3-p0 :053 > x = getSubAttributes('3C754A70BDE3')
 => "<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ws="http://ws.subscriberservices.myappliance_domain.com">n  <soapenv:Header xmlns:svsec="http://services.myappliance_domain.com">n    <svsec:username>username</svsec:username>n    <svsec:password>password</svsec:password>n  </soapenv:Header>n  <soapenv:Body>n    <ws:LookupSubscriberRequest>n      <SubscriberKey>n        <SubscriberRealmKey>n          <Name>DEFAULT</Name>n        </SubscriberRealmKey>n        <Name>3C754A70BDE3</Name>n      </SubscriberKey>n      <ResponseGroups>n        <ResponseGroup>Subscriber.Attributes</ResponseGroup>n        <ResponseGroup>Subscriber.CurrentIpAssignments</ResponseGroup>n      </ResponseGroups>n    </ws:LookupSubscriberRequest>n  </soapenv:Body>n</soapenv:Envelope>n" 
ruby-1.9.3-p0 :054 > x.class
 => String 
ruby-1.9.3-p0 :055 > x.target!
NoMethodError: undefined method `target!' for #<String:0x0000000497a348>
    from (irb):55
    from /usr/local/rvm/gems/ruby-1.9.3-p0/gems/railties-3.2.9/lib/rails/commands/console.rb:47:in `start'
    from /usr/local/rvm/gems/ruby-1.9.3-p0/gems/railties-3.2.9/lib/rails/commands/console.rb:8:in `start'
    from /usr/local/rvm/gems/ruby-1.9.3-p0/gems/railties-3.2.9/lib/rails/commands.rb:41:in `<top (required)>'
    from script/rails:6:in `require'
    from script/rails:6:in `<main>'
ruby-1.9.3-p0 :056 >

更新2

如果我不显式返回xml Builder对象,我得到一个字符串。

api = 'SubscriberServices'
@api = api.capitalize
@uname = 'username'
@pwd   = 'password'
@xml1   = "xmlns:soapenv"
@xml2   = "xmlns:ws"
@xmlns1 = "http://schemas.xmlsoap.org/soap/envelope/"
@xmlns2 = "http://ws.#{@api.downcase}.myappliance_domain.com"
def getSubAttributes(subscriber)
  request = 'LookupSubscriberRequest'
  xml = Builder::XmlMarkup.new( :indent=>2 )
  xml.soapenv:Envelope, :"#{@xml1}"=>"#{@xmlns1}", :"#{@xml2}"=>"#{@xmlns2}" do
    xml.tag!( 'soapenv:Header', :'xmlns:svsec' => 'http://services.myappliance_domain.com' ) do
      xml.tag!( 'svsec:username', @uname )
      xml.tag!( 'svsec:password', @pwd )
    end
    xml.tag!( 'soapenv:Body' ) do     
      xml.tag!( "ws:#{request}" ) do
        xml.SubscriberKey() do
          xml.SubscriberRealmKey() do
            xml.Name('DEFAULT')
          end
          xml.Name(subscriber)
        end
        xml.ResponseGroups() do
          xml.ResponseGroup('Subscriber.Attributes')
          xml.ResponseGroup('Subscriber.CurrentIpAssignments')
        end
      end
    end
  end
  return xml
end

测试……

ruby-1.9.3-p0 :294 >   api = 'SubscriberServices'
 => "SubscriberServices" 
ruby-1.9.3-p0 :295 > @api = api.capitalize
 => "Subscriberservices" 
ruby-1.9.3-p0 :296 > @uname = 'username'
 => "username" 
ruby-1.9.3-p0 :297 > @pwd   = 'password'
 => "password" 
ruby-1.9.3-p0 :298 > 
ruby-1.9.3-p0 :299 >   @xml1   = "xmlns:soapenv"
 => "xmlns:soapenv" 
ruby-1.9.3-p0 :300 > @xml2   = "xmlns:ws"
 => "xmlns:ws" 
ruby-1.9.3-p0 :301 > @xmlns1 = "http://schemas.xmlsoap.org/soap/envelope/"
 => "http://schemas.xmlsoap.org/soap/envelope/" 
ruby-1.9.3-p0 :302 > @xmlns2 = "http://ws.#{@api.downcase}.myappliance_domain.com"
 => "http://ws.subscriberservices.myappliance_domain.com" 
ruby-1.9.3-p0 :303 > 
ruby-1.9.3-p0 :304 >   def getSubAttributes(subscriber)
ruby-1.9.3-p0 :305?>     request = 'LookupSubscriberRequest'
ruby-1.9.3-p0 :306?>     
ruby-1.9.3-p0 :307 >       xml = Builder::XmlMarkup.new( :indent=>2 )
ruby-1.9.3-p0 :308?>     xml.soapenv:Envelope, :"#{@xml1}"=>"#{@xmlns1}", :"#{@xml2}"=>"#{@xmlns2}" do
ruby-1.9.3-p0 :309 >           xml.tag!( 'soapenv:Header', :'xmlns:svsec' => 'http://services.myappliance_domain.com' ) do
ruby-1.9.3-p0 :310 >               xml.tag!( 'svsec:username', @uname )
ruby-1.9.3-p0 :311?>             xml.tag!( 'svsec:password', @pwd )
ruby-1.9.3-p0 :312?>           end
ruby-1.9.3-p0 :313?>         xml.tag!( 'soapenv:Body' ) do     
ruby-1.9.3-p0 :314 >               xml.tag!( "ws:#{request}" ) do
ruby-1.9.3-p0 :315 >                   xml.SubscriberKey() do
ruby-1.9.3-p0 :316 >                       xml.SubscriberRealmKey() do
ruby-1.9.3-p0 :317 >                           xml.Name('DEFAULT')
ruby-1.9.3-p0 :318?>                       end
ruby-1.9.3-p0 :319?>                     xml.Name(subscriber)
ruby-1.9.3-p0 :320?>                   end
ruby-1.9.3-p0 :321?>                 xml.ResponseGroups() do
ruby-1.9.3-p0 :322 >                       xml.ResponseGroup('Subscriber.Attributes')
ruby-1.9.3-p0 :323?>                     xml.ResponseGroup('Subscriber.CurrentIpAssignments')
ruby-1.9.3-p0 :324?>                   end
ruby-1.9.3-p0 :325?>               end
ruby-1.9.3-p0 :326?>           end
ruby-1.9.3-p0 :327?>       end
ruby-1.9.3-p0 :328?>   
Display all 540 possibilities? (y or n)
ruby-1.9.3-p0 :328?>    xml
ruby-1.9.3-p0 :329?>   end
 => nil 
ruby-1.9.3-p0 :330 > x = getSubAttributes('3C754A70BDE3')
 => <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ws="http://ws.subscriberservices.myappliance_domain.com">
  <soapenv:Header xmlns:svsec="http://services.myappliance_domain.com">
    <svsec:username>username</svsec:username>
    <svsec:password>password</svsec:password>
  </soapenv:Header>
  <soapenv:Body>
    <ws:LookupSubscriberRequest>
      <SubscriberKey>
        <SubscriberRealmKey>
          <Name>DEFAULT</Name>
        </SubscriberRealmKey>
        <Name>3C754A70BDE3</Name>
      </SubscriberKey>
      <ResponseGroups>
        <ResponseGroup>Subscriber.Attributes</ResponseGroup>
        <ResponseGroup>Subscriber.CurrentIpAssignments</ResponseGroup>
      </ResponseGroups>
    </ws:LookupSubscriberRequest>
  </soapenv:Body>
</soapenv:Envelope>
<inspect/>
ruby-1.9.3-p0 :331 > x.class
 => "<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ws="http://ws.subscriberservices.myappliance_domain.com">n  <soapenv:Header xmlns:svsec="http://services.myappliance_domain.com">n    <svsec:username>username</svsec:username>n    <svsec:password>password</svsec:password>n  </soapenv:Header>n  <soapenv:Body>n    <ws:LookupSubscriberRequest>n      <SubscriberKey>n        <SubscriberRealmKey>n          <Name>DEFAULT</Name>n        </SubscriberRealmKey>n        <Name>3C754A70BDE3</Name>n      </SubscriberKey>n      <ResponseGroups>n        <ResponseGroup>Subscriber.Attributes</ResponseGroup>n        <ResponseGroup>Subscriber.CurrentIpAssignments</ResponseGroup>n      </ResponseGroups>n    </ws:LookupSubscriberRequest>n  </soapenv:Body>n</soapenv:Envelope>n<inspect/>n<class/>n" 
ruby-1.9.3-p0 :332 > s = x.to_xml
 => "<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ws="http://ws.subscriberservices.myappliance_domain.com">n  <soapenv:Header xmlns:svsec="http://services.myappliance_domain.com">n    <svsec:username>username</svsec:username>n    <svsec:password>password</svsec:password>n  </soapenv:Header>n  <soapenv:Body>n    <ws:LookupSubscriberRequest>n      <SubscriberKey>n        <SubscriberRealmKey>n          <Name>DEFAULT</Name>n        </SubscriberRealmKey>n        <Name>3C754A70BDE3</Name>n      </SubscriberKey>n      <ResponseGroups>n        <ResponseGroup>Subscriber.Attributes</ResponseGroup>n        <ResponseGroup>Subscriber.CurrentIpAssignments</ResponseGroup>n      </ResponseGroups>n    </ws:LookupSubscriberRequest>n  </soapenv:Body>n</soapenv:Envelope>n<inspect/>n<class/>n<to_xml/>n" 
ruby-1.9.3-p0 :333 > s.class
 => String 
ruby-1.9.3-p0 :334 > 

我不能完全看到xml对象(来自Builder::XmlMarkup.new)和params[:xml]之间的关系,但我有一个堆栈级别太深的问题,并通过使用message: xml.target!修复了这个问题。

相关内容

  • 没有找到相关文章

最新更新