Making a SOAP request by using XML in Rails
You could do this:
def post_xml(path, xml)
host = "http://demo.demo.com"
http = Net::HTTP.new(host)
resp = http.post(path, xml, { 'Content-Type' => 'application/soap+xml; charset=utf-8' })
return resp.body
end
The XML response would be returned by this method.
Soap Request Format when using Savon in ruby
The node that your Savon is producing is called token
whereas the service is expecting to receive Token
(with capital T
). As you can see, all the nodes have the same problem: they are sent with the initial letter in lowercase and they are expected to be received in uppercase.
Savon by default will convert keys to lowerCamelcase. You can change this behavior in the global convert_request_keys_to
.
The options to this global are :camelcase
, :lower_camelcase
, :upcase
and :none
.
In your problem, you should use :camelcase
.
require 'savon'
client = Savon.client(
wsdl: "http://wsportal.aaacooper.com:8188/wsGenRateEstimate.wsdl",
convert_request_keys_to: :camelcase
)
This way, you can send your request as:
request = client.build_request(:ws_gen_rate_estimate, message: { token: "XXXXX", origin_city: "Birmingham" })
And the keys will be converted to its corresponding camelcase. Note that you can write them in snakecase
and will be transformed correctly.
Sending a file with a SOAP request in Ruby
You should try to add your file in your xml request, transforming you file into a Base64 file.
file_data = Base64.encode64(File.binread("/path/to/your/file"))
Integrate that file_data
into your xml, and your full request will be something like this :
body = "<ws:action type=\"string\">ORDER_CREATE</ws:action>>
<ws:document type=\"file\" extension=\"pdf\" prefix=\"\" suffix=\"\">
<nir:data>#{file_data}</nir:data>
</ws:document>
<ws:document_name type=\"string\">pdf_file_name.pdf</ws:document_name>
<ws:get_proof type=\"string\">NO</ws:get_proof>
<ws:identifier type=\"indstringlist\" case-sensitive=\"?\">
<nir:data key=\"LOGIN\">login</nir:data>
<nir:data key=\"PASSWORD\">password</nir:data>
</ws:identifier>
<ws:mailing_type type=\"string\">UNIQUE</ws:mailing_type>
<ws:service_profile type=\"indstringlist\" case-sensitive=\"?\">
<nir:data key=\"service_id\">MAIL</nir:data>
</ws:service_profile>"
In your client.call(:order_create, soap_header: soap_header, message: body)
This should work I think !
SOAP call in Ruby on Rails using Savon gets weird around the envelope and main operation
Ok this works (verified)
@client = Savon.client(
:wsdl => 'https://testservice.postnl.com/CIF_SB/BarcodeWebService/1_1/?wsdl',
:log => true,
:wsse_auth => ['devc_!R4xc8p9', 'xxx'],
:pretty_print_xml => true,
:convert_request_keys_to => :camelcase,
:env_namespace => :s,
:namespace_identifier => nil
)
message = {
"d6p1:Message" => {
"d6p1:MessageID" => "10",
"d6p1:MessageTimeStamp" => Time.now.strftime("%d-%m-%Y %H:%M:%S")
},
"d6p1:Customer" => {
"d6p1:CustomerCode" => "DEVC",
"d6p1:CustomerNumber" => "11223344"},
"d6p1:Barcode" => {
"d6p1:Type" => "3S",
"d6p1:Range" => "DEVC",
"d6p1:Serie" => "1000000-2000000" }
}
attributes = { "xmlns:d6p1" => "http://postnl.nl/cif/domain/BarcodeWebService/",
"xmlns:i" => "http://www.w3.org/2001/XMLSchema-instance",
"xmlns" => "http://postnl.nl/cif/services/BarcodeWebService/"}
@client.call(:generate_barcode, :attributes => attributes,
:message => message,
:soap_header => { "Action" => "http://postnl.nl/cif/services/BarcodeWebService/IBarcodeWebService/GenerateBarcode"})
So the trick was adding :namespace_identifier => nil
and sending attributes
. Setting namespace_identifier removes the wsdl
from GenerateBarcode
ans attributes sets some namespaces on GenerateBarcode
tag. Now I remember why I hate SOAP so much :(
How build proper SOAP request to https://wyszukiwarkaregontest.stat.gov.pl with Savon gem
ok, this is solution to my problem:
client = Savon.client(wsdl: "https://wyszukiwarkaregontest.stat.gov.pl/wsBIR/wsdl/UslugaBIRzewnPubl.xsd", namespace: "http://CIS/BIR/PUBL/2014/07", env_namespace: :soap, use_wsa_headers: true, soap_version: 2, endpoint: "https://wyszukiwarkaregontest.stat.gov.pl/wsBIR/UslugaBIRzewnPubl.svc", namespace_identifier: :ns)
response = client.call(:zaloguj, message: { "ns:pKluczUzytkownika" => "abcde12345abcde12345" }, soap_action: "http://CIS/BIR/PUBL/2014/07/IUslugaBIRzewnPubl/Zaloguj")
I hope, you find it useful :)
Related Topics
Why Is "❨╯°□°❩╯︵┻━┻" with Such an Encoding Used for a Method Name
Does Begin . . . End While Denote a 'Block'
Ruby Gems in Stand-Alone Ruby Scripts
Rake Db:Migration Not Working on Travis-Ci Build
How to Deal with Ruby 2.1.2 Memory Leaks
Unicode Characters in Ruby 1.9.3 Irb with Rvm
How to Do Case-Insensitive Order in Rails with Postgresql
Accessing Nested Model Attributes Inside a Fields_For Without Using Formbuilder
How to Get Generators Call Other Generators in Rails 3
Dynamically Defined Setter Methods Using Define_Method
Ruby: How to Calculate a Path Relative to Another One
Example of a Prepared Insert Statement Using Ruby Pg Gem
Dynamically Create Class Attributes with Attr_Accessor
Automatically Precompile Assets Before Pushing to Heroku
How to Transfer Files Using Ssh and Scp Using Ruby Calls
API Errors Customization for Rails 3 Like Github API V3