Using Hash parameters in SOAP calls

Hi,

I can’t seem to figure out how to pass a Hash to a webservice
function. This is what I’m doing:

require "soap/wsdlDriver"
wsdl = "http://localhost:8888/cgi-bin/WebObjects/Interview.woa/ws/WebServices?wsdl"
factory = SOAP::WSDLDriverFactory.new(wsdl)
@driver = factory.createDriver

@driver.someWebserviceFunctionWithStringAndNumber(“blah”, 55)
@driver.someWebserviceFunctionWithHash({“key1” => “value1”, “key2” =>
“value2”})

someWebserviceFunctionWithStringAndNumber works fine,
someWebserviceFunctionWithHash throws up with

test_hash(WebServicesTest):
SOAP::Mapping::MappingError: Cannot map Array to SOAP/OM.
/usr/local/lib/ruby/1.8/soap/mapping/wsdlRegistry.rb:61:in
obj2soap' /usr/local/lib/ruby/1.8/soap/mapping/mapping.rb:105:in_obj2soap’
/usr/local/lib/ruby/1.8/soap/mapping/wsdlRegistry.rb:119:in
array2soap' /usr/local/lib/ruby/1.8/soap/mapping/wsdlRegistry.rb:118:ineach’
/usr/local/lib/ruby/1.8/soap/mapping/wsdlRegistry.rb:118:in
array2soap' /usr/local/lib/ruby/1.8/soap/mapping/wsdlRegistry.rb:45:inobj2soap’
/usr/local/lib/ruby/1.8/soap/mapping/mapping.rb:105:in _obj2soap' /usr/local/lib/ruby/1.8/soap/mapping/wsdlRegistry.rb:128:inelements2soap’
/usr/local/lib/ruby/1.8/soap/mapping/wsdlRegistry.rb:125:in each' /usr/local/lib/ruby/1.8/soap/mapping/wsdlRegistry.rb:125:inelements2soap’
/usr/local/lib/ruby/1.8/soap/mapping/wsdlRegistry.rb:110:in
struct2soap' /usr/local/lib/ruby/1.8/soap/mapping/wsdlRegistry.rb:43:inobj2soap’
/usr/local/lib/ruby/1.8/soap/mapping/mapping.rb:105:in _obj2soap' /usr/local/lib/ruby/1.8/soap/mapping/mapping.rb:36:inobj2soap’
/usr/local/lib/ruby/1.8/soap/wsdlDriver.rb:210:in `rpc_send’

Why is it trying to map an Array? Is Hash not supported by Ruby’s SOAP
implementation?

Thanks,
Christian

Hi,

From: “Christian Pekeler” christian@pekeler.org
Newsgroups: comp.lang.ruby
Sent: Thursday, March 18, 2004 1:54 AM

I can’t seem to figure out how to pass a Hash to a webservice
function. This is what I’m doing:

require “soap/wsdlDriver”
wsdl = “http://localhost:8888/cgi-bin/WebObjects/Interview.woa/ws/WebServices?wsdl
factory = SOAP::WSDLDriverFactory.new(wsdl)
@driver = factory.createDriver

@driver.someWebserviceFunctionWithStringAndNumber(“blah”, 55)
@driver.someWebserviceFunctionWithHash({“key1” => “value1”, “key2” =>
“value2”})

someWebserviceFunctionWithStringAndNumber works fine,
someWebserviceFunctionWithHash throws up with
[snip]

It’s a bug of SOAP4R. Serializing Hash (aka ApacheMap in
SOAP world) using WSDL fails. Thank you for finding it.

I’ll look into this and fix. For workaround, it might work.

require “soap/wsdlDriver”
wsdl = “…”
driver = SOAP::WSDLDriverFactory.new(wsdl).create_driver
driver.someWebserviceFunctionWithStringAndNumber(“blah”, 55)

backup = driver.wsdl_mapping_registry
driver.wsdl_mapping_registry = SOAP::Mapping::DefaultRegistry
driver.someWebserviceFunctionWithHash({“key1” => “value1”, “key2” => “value2”})
driver.wsdl_mapping_registry = backup

(calling other methods…)

MappingRegistry generated from WSDL does not support ApacheMap
even if the WSDL includes ApacheMap definition for now.
So I use default MappingRegistry here.

With default MappingRegistry, driver cannot understand user defined
types in WSDL so it could not work… For example, it will crash if
resulting value of someWebserviceFunctionWithHash includes
user defined type in WSDL.

Regards,
// NaHi

“NAKAMURA, Hiroshi” nahi@keynauts.com wrote in message news:

It’s a bug of SOAP4R. Serializing Hash (aka ApacheMap in
SOAP world) using WSDL fails.

I’ll look into this and fix. For workaround, it might work.

backup = driver.wsdl_mapping_registry
driver.wsdl_mapping_registry = SOAP::Mapping::DefaultRegistry
driver.someWebserviceFunctionWithHash({“key1” => “value1”, “key2” => “value2”})
driver.wsdl_mapping_registry = backup

Thank you! That workaround does work for me.

Christian