Мой клиент попросил меня интегрировать сторонний API в их приложение Rails. Единственная проблема в том, что API использует SOAP. Ruby в основном отказался от SOAP в пользу REST. Они предоставляют адаптер Java, который, по-видимому, работает с мостом Java-Ruby, но мы хотели бы сохранить все это в Ruby, если это возможно. Я посмотрел на soap4r, но, похоже, у него немного плохая репутация.
Итак, как лучше всего интегрировать вызовы SOAP в приложение Rails?
ruby-on-rails
ruby
soap
Jcoby
источник
источник
Я создал Savon, чтобы максимально упростить взаимодействие с веб-службами SOAP через Ruby.
Я рекомендую вам это проверить.
источник
Мы перешли с Handsoap на Savon.
Вот серия сообщений в блоге, в которых сравниваются две клиентские библиотеки.
источник
Еще рекомендую Савон . Я провел слишком много часов, пытаясь разобраться с Soap4R, но безрезультатно. Большой недостаток функционала, без док.
Савон - это ответ для меня.
источник
Попробуйте SOAP4R
И я только что услышал об этом в подкасте Rails Envy (эп.31):
источник
Я только что заставил мои вещи работать в течение 3 часов с помощью Savon.
Документация по началу работы на домашней странице Савона была очень простой для понимания - и фактически соответствовала тому, что я видел (не всегда так)
источник
Кент Сибилев из Datanoise также перенес библиотеку Rails ActionWebService на Rails 2.1 (и выше). Это позволяет вам предоставлять свои собственные сервисы SOAP на основе Ruby. У него даже есть режим scaffold / test, который позволяет вам тестировать свои услуги с помощью браузера.
источник
Я использовал SOAP в Ruby, когда мне приходилось создавать поддельный сервер SOAP для приемочных испытаний. Не знаю, был ли это лучший способ решить проблему, но у меня он сработал.
Я использовал Синатры камень (я писал о создании насмешливых конечных точек с Синатра здесь ) для сервера , а также Nokogiri для XML - файлов (SOAP работает с XML).
Итак, для начала я создал два файла (например, config.rb и response.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>'
В response.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
Надеюсь, вы найдете это полезным!
источник
У меня была такая же проблема, я переключился на Savon, а затем просто протестировал его на открытом WSDL (я использовал http://www.webservicex.net/geoipservice.asmx?WSDL ) и пока все хорошо!
https://github.com/savonrb/savon
источник
Я использовал 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") */
Надеюсь, это поможет. Ура.
источник