Just a word of warning. Hash tables are not a standard interop type. You will loose compatibility between SOAP implementations. I suggest you use an array of Java Beans with key/value pair concept.
Good luck, Rick Kellogg > Have you tried using the built-in HashMap type provided by apachesoap: > > > Types definition: > <schema targetNamespace="http://xml.apache.org/xml-soap" > xmlns="http://www.w3.org/2001/XMLSchema"> > <import namespace="http://schemas.xmlsoap.org/soap/encoding/" /> > <complexType name="mapItem"> > <sequence> > <element name="key" nillable="true" type="xsd:string" /> > <element name="value" nillable="true" type="xsd:string" /> > </sequence> > </complexType> > <complexType name="Map"> > <sequence> > <element maxOccurs="unbounded" minOccurs="0" name="item" > type="apachesoap:mapItem" /> > </sequence> > </complexType> > </schema> > > Message definition: > <wsdl:message name="authorizeToAuctionResponse"> > <wsdl:part name="authorizeToAuctionReturn" type="apachesoap:Map" /> > </wsdl:message> > > Works like a charm from SOAP::Lite! > > -----Original Message----- > From: Scott Ellsworth [mailto:[EMAIL PROTECTED] > Sent: Friday, December 12, 2003 2:55 PM > To: [EMAIL PROTECTED] > Subject: Proper WSDL allowing Axis to interpret a SOAP::Lite hash ref > > > Hi, all. > > I have searched the archives, but have not gotten quite enough of a > clue to solve the problem I face. I wish to use Java to get the > results from a call to a SOAP server running Perl SOAP::Lite. The > function returns a hash ref, encoded as SOAP::Lite encodes. (raw soap > call/return below.) > > I apologize for the long message, but I have found that God is in the > details in this space, and if it is just a simple typo in some routine, > the real source is required. > > The server is running SOAP::Lite 0.55. It is sending back a hashref, > and I have not been able to create the proper WSDL to see it, possibly > because of how SOAP::Lite is sending back that hashref. I can handle > simple types like ints and strings, but this is not working. > > I am using stubs created by wsdl2java, so clearly I need to express > this soap-struct in my WSDL, but I do not seem to be able to create the > proper type in the WSDL, or at least, it is not being used. > > I cannot really change the underlying routines on the server, as they > are used for many things, but I can modify the dispatch function called > by mod_perl. I have attached it at the end. > > The request: > > <?xml version="1.0" encoding="UTF-8" standalone="no"?> > <!-- > URL: http://feature.alodar.com/gbib-soap/ > --> > <soap:Envelope > xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" > soap:encodingstyle="http://schemas.xmlsoap.org/soap/encoding/" > xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" > xmlns:xsd="http://www.w3.org/2001/XMLSchema"> > <soap:Body> > <s0:get_user_ids_by_name > xmlns:s0="http://feature.alodar.com/Alodar/GBIB/UserUtils"> > <s0:arg1Name>config_name</s0:arg1Name> > <s0:arg1Value>feature</s0:arg1Value> > </s0:get_user_ids_by_name> > </soap:Body> > </soap:Envelope> > > The response: > > <?xml version="1.0" encoding="UTF-8"?> > <soap-env:envelope > xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" > xmlns:soap-enc="http://schemas.xmlsoap.org/soap/encoding/" > xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/" > xmlns:xsd="http://www.w3.org/1999/XMLSchema" > xmlns:namesp2="http://xml.apache.org/xml-soap" > soap-env:encodingstyle="http://schemas.xmlsoap.org/soap/encoding/"> > <soap-env:body> > <namesp1:get_user_ids_by_nameresponse > xmlns:namesp1="http://feature.alodar.com/Alodar/GBIB/UserUtils"> > <s-gensym3 xsi:type="namesp2:SOAPStruct"> > <admin xsi:type="xsd:int"> > 1 > </admin> > <guest xsi:type="xsd:int"> > 2 > </guest> > </s-gensym3> > </namesp1:get_user_ids_by_nameresponse> > </soap-env:body> > </soap-env:envelope> > > my WSDL: > > <?xml version="1.0" encoding="utf-8"?> > <definitions name="GBIB" > targetNamespace="http://feature.alodar.com/Alodar/GBIB/" > xmlns:schema="http://www.w3.org/2001/XMLSchema" > xmlns:tns="http://feature.alodar.com/Alodar/GBIB/" > xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" > xmlns:xml-soap="http://xml.apache.org/xml-soap" > xmlns="http://schemas.xmlsoap.org/wsdl/" > > > > <types> > <!-- I could use the following by defining the type returned from > a > part of a message as > <message name="ListOfUsers"> > <part name="models" type="tns:Vector"> > </message> > <xsd:schema > targetNamespace="http://feature.alodar.com/Alodar/GBIB/" > xmlns="http://www.w3.org/2001/XMLSchema/"> > <schema:complexType name="Vector"> > <xsd:element name="elementData" type="schema:String" /> > <xsd:element name="elementCount" type="schema:int" /> > </schema:complexType> > </xsd:schema> > --> > <schema > xmlns="http://www.w3.org/2001/XMLSchema" > targetNamespace="http://feature.alodar.com/Alodar/GBIB/" > > > <complexType name="idNameMap"> > <element name="elementData" type="string" /> > <element name="elementCount" type="int" /> > </complexType> > <complexType name="SOAPStruct"> > <all> > <element name="varString" type="string"/> > <element name="varInt" type="int"/> > </all> > </complexType> > </schema> > </types> > > <message name="config_nameRequest"> > <part name="arg1Name" type="schema:string" /> > <part name="arg1Value" type="schema:string" /> > </message> > <message name="stringStringRequest"> > <part name="arg1Name" type="schema:string" /> > <part name="arg1Value" type="schema:string" /> > <part name="arg2Name" type="schema:string" /> > <part name="arg2Value" type="schema:string" /> > </message> > <message name="stringIntRequest"> > <part name="arg1Name" type="schema:string" /> > <part name="arg1Value" type="schema:string" /> > <part name="arg2Name" type="schema:string" /> > <part name="arg2Value" type="schema:int" /> > </message> > <message name="idNameMapResponse"> > <!-- part name="idNameMapReturnValue" type="xml-soap:Map" / > --> > <part name="idNameMapReturnValue" type="tns:idNameMap" /> > </message> > <message name="stringResponse"> > <part name="stringReturnValue" type="schema:string" /> > </message> > <message name="intResponse"> > <part name="stringReturnValue" type="schema:int" /> > </message> > <message name="get_public_listsResponse"> > <part name="get_public_listsReturnValue" > type="schema:anyType" /> > </message> > > <portType name="UserUtilsPort"> > <!-- ports are analogous to method calls. SR says analogous > to > library/module/class --> > <!-- name must match some binding's type --> > <operation name="get_user_ids_by_name"> > <input message="tns:config_nameRequest" /> > <output message="tns:idNameMapResponse" /> > </operation> > <operation name="get_id_for_username"> > <input message="tns:stringStringRequest" /> > <output message="tns:intResponse" /> > </operation> > <operation name="get_username_for_id"> > <input message="tns:stringIntRequest" /> > <output message="tns:stringResponse" /> > </operation> > </portType> > > <portType name="ListUtilsPort"> > <!-- ports are analogous to method calls. --> > <!-- name must match some binding's type --> > <operation name="get_public_lists"> > <input message="tns:config_nameRequest" /> > <output message="tns:stringResponse" /> > </operation> > </portType> > > <binding name="UserUtils" type="tns:UserUtilsPort"> > <!-- binding elements tell code how to move data. We are > using SOAP > --> > <!-- These are analagous to classes --> > <!-- type matches name of some port --> > <soap:binding style="rpc" > transport="http://schemas.xmlsoap.org/soap/http" /> > <operation name="get_id_for_username"> > <soap:operation style="rpc" /> > <input> > <soap:body use="encoded" > namespace="http://feature.alodar.com/Alodar/GBIB/UserUtils" > encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" /> > </input> > <output> > <soap:body use="encoded" > namespace="http://feature.alodar.com/Alodar/GBIB/UserUtils" > encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" /> > </output> > </operation> > <operation name="get_user_ids_by_name"> > <soap:operation style="rpc" /> > <input> > <soap:body use="encoded" > namespace="http://feature.alodar.com/Alodar/GBIB/UserUtils" > encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" /> > </input> > <output> > <soap:body use="encoded" > namespace="http://feature.alodar.com/Alodar/GBIB/UserUtils" > encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" /> > </output> > </operation> > <operation name="get_username_for_id"> > <soap:operation style="rpc" /> > <input> > <soap:body use="encoded" > namespace="http://feature.alodar.com/Alodar/GBIB/UserUtils" > encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" /> > </input> > <output> > <soap:body use="encoded" > namespace="http://feature.alodar.com/Alodar/GBIB/UserUtils" > encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" /> > </output> > </operation> > </binding> > > <binding name="ListUtils" type="tns:ListUtilsPort"> > <!-- binding elements tell code how to move data. We are > using SOAP > --> > <!-- These are analagous to classes --> > <!-- type matches name of some port --> > <soap:binding style="rpc" > transport="http://schemas.xmlsoap.org/soap/http" /> > <operation name="get_public_lists"> > <soap:operation style="rpc" /> > <input> > <soap:body use="encoded" > namespace="http://feature.alodar.com/Alodar/GBIB/ListUtils" > encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" /> > </input> > <output> > <soap:body use="encoded" > namespace="http://feature.alodar.com/Alodar/GBIB/ListUtils" > encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" /> > </output> > </operation> > </binding> > > <service name="GBIBService"> > <!-- service tells us what bindings to use. These give > actual > machines that implement the protocol. --> > <!-- document> > For a complete description of this service, go to > the following URL: > <a href="http://feature.alodar.com/"> > http://feature.alodar.com/ > </a> > </document --> > <port name="UserUtils" binding="tns:UserUtils"> > <soap:address > location="http://feature.alodar.com/gbib-soap" /> > </port> > <port name="ListUtils" binding="tns:ListUtils"> > <soap:address > location="http://feature.alodar.com/gbib-soap" /> > </port> > </service> > </definitions> > > The java code: > > public void callFeatureStub() { > try{ > String endpoint = > "http://feature.alodar.com/gbib-soap/"; > > UserUtilsPort userUtilsPort = new > GBIBServiceLocator().getUserUtils(new URL(endpoint)); > ((UserUtilsStub)userUtilsPort).setTimeout(60000); > ListUtilsPort listUtilsPort = new > GBIBServiceLocator().getListUtils(new URL(endpoint)); > ((ListUtilsStub)listUtilsPort).setTimeout(60000); > > // works great! > > int > get_id_for_usernameResult=userUtilsPort.get_id_for_username("config_name > ", config_name, "username", "admin"); > printResult("get_id_for_username", > get_id_for_usernameResult); > > //works great! > > String > get_username_for_idResult=userUtilsPort.get_username_for_id("config_name > ", config_name, "user_id", 1); > printResult("get_username_for_id", > get_username_for_idResult); > > // throws exception > Object get_user_ids_by_nameResult = > userUtilsPort.get_user_ids_by_name("config_name", config_name); > printResult("get_user_ids_by_name", > get_user_ids_by_nameResult); > > } catch (Exception e) { > System.err.println("Error: "+e.toString()); > } > } > > The dispatcher is very simple: > > sub handler { > SOAP::Transport::HTTP::Apache -> dispatch_to( > qw( > Alodar::GBIB::ListUtils::get_public_lists > Alodar::GBIB::UserUtils::get_id_for_username > Alodar::GBIB::UserUtils::get_user_ids_by_name > Alodar::GBIB::UserUtils::get_username_for_id > ) > ) ->handler(@_) > > I can add more things to this, as long as they can go here. > > The exception is: > > [java] Result of get_id_for_username was type int, value 1 > [java] Result of get_username_for_id was type java.lang.String, > value admin > [java] - Exception: > [java] org.xml.sax.SAXException: Deserializing parameter > 's-gensym39': could not find deserializer for type > {http://xml.apache.org/xml-soap}SOAPStruct > [java] at > org.apache.axis.message.RPCHandler.onStartChild(RPCHandler.java:302) > [java] Error: org.xml.sax.SAXException: Deserializing parameter > 's-gensym39': could not find deserializer for type > {http://xml.apache.org/xml-soap}SOAPStruct > [java] at > org.apache.axis.encoding.DeserializationContextImpl.startElement(Deseria > lizationContextImpl.java:963) > [java] at > org.apache.axis.message.SAX2EventRecorder.replay(SAX2EventRecorder.java: > 198) > [java] at > org.apache.axis.message.MessageElement.publishToHandler(MessageElement.j > ava:722) > [java] at > org.apache.axis.message.RPCElement.deserialize(RPCElement.java:233) > [java] at > org.apache.axis.message.RPCElement.getParams(RPCElement.java:347) > [java] at org.apache.axis.client.Call.invoke(Call.java:2272) > [java] at org.apache.axis.client.Call.invoke(Call.java:2171) > [java] at org.apache.axis.client.Call.invoke(Call.java:1691) > [java] at > com.alodar.feature.Alodar.GBIB.UserUtilsStub.get_user_ids_by_name(UserUt > ilsStub.java:187) > [java] at axisTest.callFeatureStub(axisTest.java:71) > [java] at axisTest.main(axisTest.java:46) > > Scott
