91

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

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

4

10 回答 10

171

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

于 2010-01-18T18:54:36.673 回答
36

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

示例代码:

require 'soap/wsdlDriver'

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

就是这样

于 2008-09-03T00:27:21.393 回答
13

我们从 Handsoap 切换到 Savon。

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

于 2010-01-18T18:42:49.947 回答
5

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

萨文是我的答案。

于 2010-03-12T11:05:53.767 回答
4

尝试SOAP4R

我刚刚在 Rails Envy 播客(第 31 页)上听说了这个:

于 2008-09-02T19:05:10.560 回答
3

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

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

于 2011-05-26T14:36:24.813 回答
2

来自Datanoise的Kent Sibilev也将 Rails ActionWebService 库移植到 Rails 2.1(及更高版本)。这允许您公开自己的基于 Ruby 的 SOAP 服务。他甚至有一个脚手架/测试模式,允许您使用浏览器测试您的服务。

于 2009-07-30T17:47:11.197 回答
2

我使用如下 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")
*/

希望能帮助到你。干杯。

于 2016-02-02T12:03:06.813 回答
2

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

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

因此,一开始我创建了两个文件(例如 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>'

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

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

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

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

于 2016-06-07T10:05:57.610 回答
1

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

https://github.com/savonrb/savon

于 2014-10-08T17:37:11.113 回答