axis-java-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Gurkan, Ozzie (MAN-Corporate)" <Ozzie.Gur...@cox.com>
Subject RE: Proper WSDL allowing Axis to interpret a SOAP::Lite hash ref
Date Fri, 12 Dec 2003 20:26:51 GMT
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:scott@alodar.com] 
Sent: Friday, December 12, 2003 2:55 PM
To: axis-user@ws.apache.org
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

Mime
View raw message