在 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
What's the best way to use SOAP with Ruby?
提问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
回答by phoet
We switched from Handsoap to Savon.
我们从 Handsoap 切换到 Savon。
Here is a series of blog postscomparing the two client libraries.
回答by brunetton
回答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)上对其进行了测试,到目前为止一切顺利!
回答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.
希望能帮助到你。干杯。

