在 Ruby 中使用 SOAP 的最佳方式是什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/40273/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 19:04:15  来源:igfitidea点击:

What's the best way to use SOAP with Ruby?

ruby-on-railsrubysoap

提问by jcoby

A client of mine has asked me to integrate a 3rd party API into their Rails app. The only problem is that the API uses SOAP. Ruby has basically dropped SOAP in favor of REST. They provide a Java adapter that apparently works with the Java-Ruby bridge, but we'd like to keep it all in Ruby, if possible. I looked into soap4r, but it seems to have a slightly bad reputation.

我的一个客户要求我将 3rd 方 API 集成到他们的 Rails 应用程序中。唯一的问题是 API 使用 SOAP。Ruby 基本上已经放弃了 SOAP 以支持 REST。他们提供了一个 Java 适配器,显然可以与 Java-Ruby 桥一起使用,但如果可能,我们希望将其全部保留在 Ruby 中。我查看了soap4r,但它的名声似乎有点差。

So what's the best way to integrate SOAP calls into a Rails app?

那么将 SOAP 调用集成到 Rails 应用程序中的最佳方法是什么?

采纳答案by Orion Edwards

We used the built in soap/wsdlDriverclass, which is actually SOAP4R. It's dog slow, but really simple. The SOAP4R that you get from gems/etc is just an updated version of the same thing.

我们使用了内置soap/wsdlDriver类,它实际上是 SOAP4R。这很慢,但非常简单。您从 gems/etc 获得的 SOAP4R 只是同一事物的更新版本。

Example code:

示例代码:

require 'soap/wsdlDriver'

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

That's about it

就是这样

回答by rubiii

I built Savonto make interacting with SOAP webservices via Ruby as easy as possible.
I'd recommend you check it out.

我构建Savon 是为了尽可能轻松地通过 Ruby 与 SOAP Web 服务进行交互。
我建议你检查一下。

回答by phoet

We switched from Handsoap to Savon.

我们从 Handsoap 切换到 Savon。

Here is a series of blog postscomparing the two client libraries.

这是一系列比较两个客户端库的博客文章

回答by brunetton

I also recommend Savon. I spent too many hours trying to deal with Soap4R, without results. Big lack of functionality, no doc.

我也推荐萨翁。我花了太多时间试图处理 Soap4R,但没有结果。严重缺乏功能,没有文档。

Savon is the answer for me.

萨翁是我的答案。

回答by ChrisW

Just got my stuff working within 3 hours using Savon.

使用 Savon 在 3 小时内让我的东西工作起来。

The Getting Started documentation on Savon's homepage was really easy to follow - and actually matched what I was seeing (not always the case)

Savon 主页上的入门文档真的很容易理解 - 实际上与我所看到的相符(并非总是如此)

回答by Jason Navarrete

Try SOAP4R

尝试SOAP4R

And I just heard about this on the Rails Envy Podcast (ep 31):

我刚刚在 Rails Envy Podcast(第 31 集)上听说过这个:

回答by Philippe Monnet

Kent Sibilev from Datanoisehad also ported the Rails ActionWebService library to Rails 2.1 (and above). This allows you to expose your own Ruby-based SOAP services. He even has a scaffold/test mode which allows you to test your services using a browser.

从肯特Sibilev Datanoise也移植了Rails ActionWebService库的Rails 2.1(及以上)。这允许您公开自己的基于 Ruby 的 SOAP 服务。他甚至有一个脚手架/测试模式,允许您使用浏览器测试您的服务。

回答by Radu Rosu

I have used SOAP in Ruby when i've had to make a fake SOAP server for my acceptance tests. I don't know if this was the best way to approach the problem, but it worked for me.

当我不得不为我的验收测试制作一个假的 SOAP 服务器时,我在 Ruby 中使用了 SOAP。我不知道这是否是解决问题的最佳方法,但它对我有用。

I have used Sinatra gem (I wrote about creating mocking endpoints with Sinatra here) for server and also Nokogirifor XML stuff (SOAP is working with XML).

我已经将 Sinatra gem(我在这里写了关于使用 Sinatra 创建模拟端点的文章)用于服务器,还使用了Nokogiri用于 XML 内容(SOAP 正在使用 XML)。

So, for the beginning I have create two files (e.g. config.rb and responses.rb) in which I have put the predefined answers that SOAP server will return. In config.rbI have put the WSDL file, but as a string.

因此,一开始我创建了两个文件(例如config.rb 和responses.rb),我在其中放置了SOAP 服务器将返回的预定义答案。在config.rb我已经把 WSDL 文件,但作为一个字符串。

@@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 responses.rbI have put samples for responses that SOAP server will return for different scenarios.

responses.rb 中,我已经放置了SOAP 服务器将针对不同场景返回的响应示例。

@@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>"

So now let me show you how I have actually created the server.

现在让我向您展示我实际上是如何创建服务器的。

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

I hope you'll find this helpful!

我希望你会发现这有帮助!

回答by Ecommerce-Technician

I was having the same issue, switched to Savon and then just tested it on an open WSDL (I used http://www.webservicex.net/geoipservice.asmx?WSDL) and so far so good!

我遇到了同样的问题,切换到 Savon,然后在开放的 WSDL(我使用了http://www.webservicex.net/geoipservice.asmx?WSDL)上对其进行了测试,到目前为止一切顺利!

https://github.com/savonrb/savon

https://github.com/savonrb/savon

回答by Raja

I have used HTTP call like below to call a SOAP method,

我已经使用像下面这样的 HTTP 调用来调用 SOAP 方法,

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")
*/

Hope it helps. Cheers.

希望能帮助到你。干杯。