You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-user@axis.apache.org by "Martin, Imme" <im...@sap.com> on 2005/12/08 10:29:11 UTC

Deserializing complex/nested types

Hallo all, 

this most probably is a stupid or at least simple question: How can I
deserialize a complex Object which is returned from a Webservice
implemented in .NET into some nice Java Object? 

My scenario looks as follows: 

// The Environment
I am running Apache Axis 1.3, Build date Oct. 5th, 2005

// The Service
I have a service, implemented in C# on some IIS machine. This service
returns a complex BusinessPartnerElements object. This object consists
of several sub-objects like Person which itself consists of Name,
Firstname, Tile and Sex which are Strings. 

// The Client
The Java Client only wants to call the service and retrieve the
BusinessPartnerElements object. Nothing more so far. Calling the service
works and I received a SOAP response which looks pretty good to me: 

<SOAP Response>
<?xml version="1.0" encoding="utf-8"?>

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">

	<soap:Body>
		<BusinessPartnerRetrieveInResponse
xmlns="http://sap.com/composite/prototype/webshop">
			<ID xmlns="">123456</ID>
			<Organization xmlns="">
				<CompanyName>myCorp</CompanyName>
				<LegalForm>Inc</LegalForm>
			</Organization>
			<Person xmlns="">
				<Firstname>John</Firstname>
				<Lastname>Doe</Lastname>
				<Title>Phd</Title>
				<Sex>male</Sex>
			</Person>
			<Telefon xmlns="">
				<Number>555 3535</Number>
				<Extension>01</Extension>
	
<ValidityStartDate>0001-01-01</ValidityStartDate>
	
<ValidityEndDate>0001-01-01</ValidityEndDate>
			</Telefon>
			<Email xmlns="">
				<Address
protocolCode="SMTP">jdoe@mycorp.com</Address>
	
<ValidityStartDate>0001-01-01</ValidityStartDate>
	
<ValidityEndDate>0001-01-01</ValidityEndDate>
			</Email>
			<WebAddress xmlns="">
	
<Address>http://www.mycorp.com/jdoe</Address>
			</WebAddress>
			<Address xmlns="">
				<City>London</City>
				<PostalCode>NW23</PostalCode>
				<Street>Abbey Road</Street>
				<Building>4</Building>
	
<ValidityStartDate>0001-01-01</ValidityStartDate>
	
<ValidityEndDate>0001-01-01</ValidityEndDate>
			</Address>
		</BusinessPartnerRetrieveInResponse>
	</soap:Body>
</soap:Envelope>
</SOAP Response>

>From the WSDL file, I was able to create a bunch of Java proxy classes
which can hold the BusinessPartnerElements Object. In order to tell Axis
how to map the received stuff, I thought it would be enough to do
something like this: 

<code>

String endpoint = "http://p122851/WebService1/ShopService.asmx";
Service service = new Service();

Call call = (Call) service.createCall();
call.setTargetEndpointAddress(new java.net.URL(endpoint));
call.setOperationName(new
QName("http://sap.com/composite/prototype/webshop",
"BusinessPartnerRetrieveIn"));
call.setSOAPActionURI("http://sap.com/composite/prototype/webshop/Busine
ssPartnerRetrieveIn");

// take care about the type mapping...
qn = new QName( "urn:BusinessPartnerRetrieveIn",
"BusinessPartnerElements" );  // BTW: it does not matter hat values are
given for qn - the Exception remains the same :(
BeanSerializerFactory bsf = new
BeanSerializerFactory(BusinessPartnerElements.class, qn);
BeanDeserializerFactory bdsf = new
BeanDeserializerFactory(BusinessPartnerElements.class, qn);

call.registerTypeMapping(BusinessPartnerElements.class, qn, bsf, bdsf);
call.setReturnType( qn ); // Return type is our bean
BusinessPartnerElements pbe = (BusinessPartnerElements)call.invoke(new
Object[] {});

</code>

But unfortunately, this throws an Exception: 

<exception>

org.xml.sax.SAXException: Invalid element in
<package>.BusinessPartnerElements - CompanyName

</exception>

This CompanyName Elements which SAX is complaining about is the first
non-complex Object [String] of the first somplex sub-object,
Organization. The BusinessPartnerElements Object looks somethig like
this: 
 
BusinessPartnerElements
'--> ID (String)
'--> Organization (complex)
_ _ _'--> CompanyName (String)
_ _ _'--> LegalForm (String)
'--> Person (complex)
_ _ _'--> Firstname (String)
.
.
.

So, Axis does not have an issue with the ID thing but stumbles over the
complex sub-types. My Idea was to somehow tell Axis about these complex
sub-types and how to map them, just like I did with the root element
[see code above] but I simply don't know _HOW_ All I read in the Axis
Wiki is that Axis *can* handle these complex return types but I never
found a description _how_. Also, the axis guides only respond with some
Objects which only consist of simple types themselves. I really hope
that you can help me with this since it really is a very important topic
for me...

If you have any questions, feel free to ask, I will provide code and
whatever you need. Also, I could send you a postcard or even home-made
cookies if that motivates you ;)

I thank you very, very much for helping me!

Cheers, 
Martin

Re: Deserializing complex/nested types

Posted by Davanum Srinivas <da...@gmail.com>.
Please run wsdl2java against your wsdl and review the generated code,
especially stubs and wsdd. You will be able to cut and paste from
there to get this working.

thanks,
dims

On 12/8/05, Martin, Imme <im...@sap.com> wrote:
> Hallo all,
>
> this most probably is a stupid or at least simple question: How can I
> deserialize a complex Object which is returned from a Webservice
> implemented in .NET into some nice Java Object?
>
> My scenario looks as follows:
>
> // The Environment
> I am running Apache Axis 1.3, Build date Oct. 5th, 2005
>
> // The Service
> I have a service, implemented in C# on some IIS machine. This service
> returns a complex BusinessPartnerElements object. This object consists
> of several sub-objects like Person which itself consists of Name,
> Firstname, Tile and Sex which are Strings.
>
> // The Client
> The Java Client only wants to call the service and retrieve the
> BusinessPartnerElements object. Nothing more so far. Calling the service
> works and I received a SOAP response which looks pretty good to me:
>
> <SOAP Response>
> <?xml version="1.0" encoding="utf-8"?>
>
> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
> xmlns:xsd="http://www.w3.org/2001/XMLSchema">
>
>         <soap:Body>
>                 <BusinessPartnerRetrieveInResponse
> xmlns="http://sap.com/composite/prototype/webshop">
>                         <ID xmlns="">123456</ID>
>                         <Organization xmlns="">
>                                 <CompanyName>myCorp</CompanyName>
>                                 <LegalForm>Inc</LegalForm>
>                         </Organization>
>                         <Person xmlns="">
>                                 <Firstname>John</Firstname>
>                                 <Lastname>Doe</Lastname>
>                                 <Title>Phd</Title>
>                                 <Sex>male</Sex>
>                         </Person>
>                         <Telefon xmlns="">
>                                 <Number>555 3535</Number>
>                                 <Extension>01</Extension>
>
> <ValidityStartDate>0001-01-01</ValidityStartDate>
>
> <ValidityEndDate>0001-01-01</ValidityEndDate>
>                         </Telefon>
>                         <Email xmlns="">
>                                 <Address
> protocolCode="SMTP">jdoe@mycorp.com</Address>
>
> <ValidityStartDate>0001-01-01</ValidityStartDate>
>
> <ValidityEndDate>0001-01-01</ValidityEndDate>
>                         </Email>
>                         <WebAddress xmlns="">
>
> <Address>http://www.mycorp.com/jdoe</Address>
>                         </WebAddress>
>                         <Address xmlns="">
>                                 <City>London</City>
>                                 <PostalCode>NW23</PostalCode>
>                                 <Street>Abbey Road</Street>
>                                 <Building>4</Building>
>
> <ValidityStartDate>0001-01-01</ValidityStartDate>
>
> <ValidityEndDate>0001-01-01</ValidityEndDate>
>                         </Address>
>                 </BusinessPartnerRetrieveInResponse>
>         </soap:Body>
> </soap:Envelope>
> </SOAP Response>
>
> From the WSDL file, I was able to create a bunch of Java proxy classes
> which can hold the BusinessPartnerElements Object. In order to tell Axis
> how to map the received stuff, I thought it would be enough to do
> something like this:
>
> <code>
>
> String endpoint = "http://p122851/WebService1/ShopService.asmx";
> Service service = new Service();
>
> Call call = (Call) service.createCall();
> call.setTargetEndpointAddress(new java.net.URL(endpoint));
> call.setOperationName(new
> QName("http://sap.com/composite/prototype/webshop",
> "BusinessPartnerRetrieveIn"));
> call.setSOAPActionURI("http://sap.com/composite/prototype/webshop/Busine
> ssPartnerRetrieveIn");
>
> // take care about the type mapping...
> qn = new QName( "urn:BusinessPartnerRetrieveIn",
> "BusinessPartnerElements" );  // BTW: it does not matter hat values are
> given for qn - the Exception remains the same :(
> BeanSerializerFactory bsf = new
> BeanSerializerFactory(BusinessPartnerElements.class, qn);
> BeanDeserializerFactory bdsf = new
> BeanDeserializerFactory(BusinessPartnerElements.class, qn);
>
> call.registerTypeMapping(BusinessPartnerElements.class, qn, bsf, bdsf);
> call.setReturnType( qn ); // Return type is our bean
> BusinessPartnerElements pbe = (BusinessPartnerElements)call.invoke(new
> Object[] {});
>
> </code>
>
> But unfortunately, this throws an Exception:
>
> <exception>
>
> org.xml.sax.SAXException: Invalid element in
> <package>.BusinessPartnerElements - CompanyName
>
> </exception>
>
> This CompanyName Elements which SAX is complaining about is the first
> non-complex Object [String] of the first somplex sub-object,
> Organization. The BusinessPartnerElements Object looks somethig like
> this:
>
> BusinessPartnerElements
> '--> ID (String)
> '--> Organization (complex)
> _ _ _'--> CompanyName (String)
> _ _ _'--> LegalForm (String)
> '--> Person (complex)
> _ _ _'--> Firstname (String)
> .
> .
> .
>
> So, Axis does not have an issue with the ID thing but stumbles over the
> complex sub-types. My Idea was to somehow tell Axis about these complex
> sub-types and how to map them, just like I did with the root element
> [see code above] but I simply don't know _HOW_ All I read in the Axis
> Wiki is that Axis *can* handle these complex return types but I never
> found a description _how_. Also, the axis guides only respond with some
> Objects which only consist of simple types themselves. I really hope
> that you can help me with this since it really is a very important topic
> for me...
>
> If you have any questions, feel free to ask, I will provide code and
> whatever you need. Also, I could send you a postcard or even home-made
> cookies if that motivates you ;)
>
> I thank you very, very much for helping me!
>
> Cheers,
> Martin
>


--
Davanum Srinivas : http://wso2.com/blogs/