Frage

Ein Kunde von mir hat mich gebeten, eine Drittanbieter-API in seine Rails-App zu integrieren.Das einzige Problem besteht darin, dass die API SOAP verwendet.Ruby hat SOAP grundsätzlich zugunsten von REST aufgegeben.Sie stellen einen Java-Adapter bereit, der offenbar mit der Java-Ruby-Brücke funktioniert, aber wir möchten, wenn möglich, alles in Ruby behalten.Ich habe mir Soap4r angesehen, aber es scheint einen etwas schlechten Ruf zu haben.

Was ist also der beste Weg, SOAP-Aufrufe in eine Rails-App zu integrieren?

War es hilfreich?

Lösung

Wir haben den eingebauten genutzt soap/wsdlDriver Klasse, die eigentlich SOAP4R ist.Es ist hundelangsam, aber wirklich einfach.Das SOAP4R, das Sie von gems/etc erhalten, ist nur eine aktualisierte Version desselben.

Beispielcode:

require 'soap/wsdlDriver'

client = SOAP::WSDLDriverFactory.new( 'http://example.com/service.wsdl' ).create_rpc_driver
result = client.doStuff();

Das ist alles

Andere Tipps

ich baue Savon um die Interaktion mit SOAP-Webservices über Ruby so einfach wie möglich zu gestalten.
Ich würde Ihnen empfehlen, es sich anzusehen.

Wir sind von Handseife auf Savon umgestiegen.

Hier ist ein Reihe von Blogbeiträgen Vergleich der beiden Client-Bibliotheken.

Ich empfehle auch Savon.Ich habe zu viele Stunden damit verbracht, mich mit Soap4R auseinanderzusetzen, ohne Ergebnisse.Großer Mangel an Funktionalität, kein Dokument.

Savon ist die Antwort für mich.

Versuchen SOAP4R

Und davon habe ich gerade im Rails Envy Podcast (Folge 31) gehört:

Mit Savon habe ich meine Sachen innerhalb von 3 Stunden zum Laufen gebracht.

Die „Erste Schritte“-Dokumentation auf Savons Homepage war wirklich einfach zu verstehen – und stimmte tatsächlich mit dem überein, was ich sah (was nicht immer der Fall war).

Kent Sibilev aus Datenrauschen hatte auch die Rails ActionWebService-Bibliothek auf Rails 2.1 (und höher) portiert.Dadurch können Sie Ihre eigenen Ruby-basierten SOAP-Dienste bereitstellen.Er verfügt sogar über einen Gerüst-/Testmodus, der es Ihnen ermöglicht, Ihre Dienste mithilfe eines Browsers zu testen.

Ich hatte das gleiche Problem, wechselte zu Savon und testete es dann einfach auf einer offenen WSDL (die ich verwendet habe). http://www.webservicex.net/geoipservice.asmx?WSDL) und soweit so gut!

https://github.com/savonrb/savon

Ich habe SOAP in Ruby verwendet, als ich für meine Abnahmetests einen gefälschten SOAP-Server erstellen musste.Ich weiß nicht, ob dies der beste Weg war, das Problem anzugehen, aber bei mir hat es funktioniert.

Ich habe Sinatra Gem verwendet (ich habe über die Erstellung von Spott-Endpunkten mit Sinatra geschrieben). Hier) für Server und auch Nokogiri für XML-Sachen (SOAP arbeitet mit XML).

Also habe ich zunächst zwei Dateien erstellt (z. B.config.rb und Responses.rb), in die ich die vordefinierten Antworten eingefügt habe, die der SOAP-Server zurückgeben wird.In config.rb Ich habe die WSDL-Datei abgelegt, aber als String.

@@wsdl = '<wsdl:definitions name="StockQuote"
         targetNamespace="http://example.com/stockquote.wsdl"
         xmlns:tns="http://example.com/stockquote.wsdl"
         xmlns:xsd1="http://example.com/stockquote.xsd"
         xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
         xmlns="http://schemas.xmlsoap.org/wsdl/">
         .......
      </wsdl:definitions>'

In Antworten.rb Ich habe Beispiele für Antworten bereitgestellt, die der SOAP-Server für verschiedene Szenarien zurückgibt.

@@login_failure = "<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
    <s:Body>
        <LoginResponse xmlns="http://tempuri.org/">
            <LoginResult xmlns:a="http://schemas.datacontract.org/2004/07/WEBMethodsObjects" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
                <a:Error>Invalid username and password</a:Error>
                <a:ObjectInformation i:nil="true"/>
                <a:Response>false</a:Response>
            </LoginResult>
        </LoginResponse>
    </s:Body>
</s:Envelope>"

Lassen Sie mich Ihnen nun zeigen, wie ich den Server tatsächlich erstellt habe.

require 'sinatra'
require 'json'
require 'nokogiri'
require_relative 'config/config.rb'
require_relative 'config/responses.rb'

after do
# cors
headers({
    "Access-Control-Allow-Origin" => "*",
    "Access-Control-Allow-Methods" => "POST",
    "Access-Control-Allow-Headers" => "content-type",
})

# json
content_type :json
end

#when accessing the /HaWebMethods route the server will return either the WSDL file, either and XSD (I don't know exactly how to explain this but it is a WSDL dependency)
get "/HAWebMethods/" do
  case request.query_string
    when 'xsd=xsd0'
        status 200
        body = @@xsd0
    when 'wsdl'
        status 200
        body = @@wsdl
  end
end

post '/HAWebMethods/soap' do
request_payload = request.body.read
request_payload = Nokogiri::XML request_payload
request_payload.remove_namespaces!

if request_payload.css('Body').text != ''
    if request_payload.css('Login').text != ''
        if request_payload.css('email').text == some username && request_payload.css('password').text == some password
            status 200
            body = @@login_success
        else
            status 200
            body = @@login_failure
        end
    end
end
end

Ich hoffe, Sie finden das hilfreich!

Ich habe einen HTTP-Aufruf wie unten verwendet, um eine SOAP-Methode aufzurufen:

require 'net/http'

class MyHelper
  def initialize(server, port, username, password)
    @server = server
    @port = port
    @username = username
    @password = password

    puts "Initialised My Helper using #{@server}:#{@port} username=#{@username}"
  end



  def post_job(job_name)

    puts "Posting job #{job_name} to update order service"

    job_xml ="<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:ns=\"http://test.com/Test/CreateUpdateOrders/1.0\">
    <soapenv:Header/>
    <soapenv:Body>
       <ns:CreateTestUpdateOrdersReq>
          <ContractGroup>ITE2</ContractGroup>
          <ProductID>topo</ProductID>
          <PublicationReference>#{job_name}</PublicationReference>
       </ns:CreateTestUpdateOrdersReq>
    </soapenv:Body>
 </soapenv:Envelope>"

    @http = Net::HTTP.new(@server, @port)
    puts "server: " + @server  + "port  : " + @port
    request = Net::HTTP::Post.new(('/XISOAPAdapter/MessageServlet?/Test/CreateUpdateOrders/1.0'), initheader = {'Content-Type' => 'text/xml'})
    request.basic_auth(@username, @password)
    request.body = job_xml
    response = @http.request(request)

    puts "request was made to server " + @server

    validate_response(response, "post_job_to_pega_updateorder job", '200')

  end



  private 

  def validate_response(response, operation, required_code)
    if response.code != required_code
      raise "#{operation} operation failed. Response was [#{response.inspect} #{response.to_hash.inspect} #{response.body}]"
    end
  end
end

/*
test = MyHelper.new("mysvr.test.test.com","8102","myusername","mypassword")
test.post_job("test_201601281419")
*/

Ich hoffe es hilft.Prost.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top