与Ruby一起使用SOAP的最佳方式是什么?
我的一个客户要求我将第三方API集成到他们的Rails应用程序中。 唯一的问题是API使用SOAP。 Ruby已经基本上放弃了SOAP,转而使用REST。 他们提供了一个Java适配器,显然可以与Java-Ruby桥接器配合使用,但是如果可能的话,我们想把它全部保存在Ruby中。 我看着soap4r,但它似乎有一个不好的名声。
那么,将SOAP调用集成到Rails应用程序中的最佳方式是什么?
我们使用了内置的soap/wsdlDriver
类,它实际上是SOAP4R。 这是狗慢,但很简单。 您从gem / etc获得的SOAP4R只是同一事物的更新版本。
示例代码:
require 'soap/wsdlDriver' client = SOAP::WSDLDriverFactory.new( 'http://example.com/service.wsdl' ).create_rpc_driver result = client.doStuff();
就是这样
我build立了Savon ,通过Ruby与SOAP web服务交互,尽可能简单。
我build议你检查一下。
我们从Handsoap转到Savon。
这是一系列比较两个客户端库的博客文章 。
我也推荐Savon http://wiki.github.com/rubiii/savon 。 我花了太多时间来处理Soap4R,没有结果。 缺乏function,没有文档。
萨龙是我的答案。
尝试SOAP4R
- SOAP4R
- SOAP4R入门
我刚刚在Rails Envy Podcast(ep 31)上听说过这个:
- WS-Deathstar SOAP演练
刚刚拿到我的东西在3个小时内使用萨翁。
Savon主页上的Getting Started文档非常易于使用 – 而且实际上与我所看到的相符(并非总是如此)
来自Datanoise的 Kent Sibilev也将Rails ActionWebService库移植到了Rails 2.1(及以上版本)。 这使您可以公开您自己的基于Ruby的SOAP服务。 他甚至有一个脚手架/testing模式,允许您使用浏览器testing您的服务。
我在Ruby中使用SOAP时,必须为我的验收testing制作一个假的SOAP服务器。 我不知道这是否是解决这个问题的最好方法,但是对我有用。
我已经使用了Sinatra gem(我写了关于在这里用Sinatra创build模拟端点)和服务器的Nokogiri (SOAP正在使用XML)。
所以,一开始我已经创build了两个文件(例如config.rb和respond.rb),其中我已经放置了SOAP服务器将返回的预定义答案。 在config.rb我已经把WSDL文件,但作为一个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>'
在respond.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>"
所以现在让我告诉你我是如何创build服务器的。
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
我希望你会觉得这有帮助!
我有同样的问题,切换到萨翁,然后在一个开放的WSDL(我使用http://www.webservicex.net/geoipservice.asmx?WSDL )testing它,到目前为止这么好!
我用下面的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") */
希望它有帮助。 干杯。