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 John Menke <jo...@eagleinfosystems.com> on 2004/11/11 21:42:11 UTC

How to learn complex object serialization?

I've been having problems with trying to get axis to serialize / deserialize
a set of two beans where one bean contains a reference to the other bean --
my service also returns an array of these complex objects.

Can somebody point me to any resources for doing this?  I have asked a few
questions on the list but i have not made any progress so far.

please help?

-jm


RE: typeMapping and Bad Types

Posted by John Menke <jo...@eagleinfosystems.com>.
Kevin,

are you using the beanMapping or typeMapping tags in your wsdd?  I don't see
a reference to them in this email.

-jm

-----Original Message-----
From: Kevin J. Duling [mailto:jattier@hotmail.com]
Sent: Saturday, November 13, 2004 1:24 AM
To: axis-user@ws.apache.org
Subject: Re: typeMapping and Bad Types


I'm a little closer; I've found another piece of the puzzle.  I didn't
understand what "SAXException: Bad types (classA -> classB)" meant.  While
working on the server-side of my app, I created this same problem by
returning the wrong object type.  So I'm assuming this message is similar to
a ClassCastException.

In my own situation, I'm able to deserialize a TResult object when it is the
only object in the message.  But when two objects are there, deserialization
doesn't work.  I've also found when I return a TResult object and a second
object that's "nil", deserialization works.

What I don't understand is why deserializing the 2nd object doesn't work
even though my WSDL distintly says that a GetCustomerFinancialsResponse will
consist of both a TResult and a TCustomerFinancials.

I don't see any point where I load the WSDL in as a resource.  I've only
generated code with WSDL2Java.  Am I supposed to set the location of the
WSDL in the code somewhere?

Here are the relevant pieces from the WSDL:

  <message name="CustomerFinancialGet2Request">
    <part name="CustomerID" type="ns1:TCustomerID"/>
    <part name="CustomerFinancial" type="ns1:TCustomerFinancial"/>
  </message>
  <message name="CustomerFinancialGet2Response">
    <part name="CustomerFinancial" type="ns1:TCustomerFinancial"/>
    <part name="return" type="ns2:TResult"/>
  </message>
    .
    .
    .
<portType name="IOBISMSClient">
    <operation name="CustomerFinancialGet">
      <input message="tns:CustomerFinancialGet2Request"/>
      <output message="tns:CustomerFinancialGet2Response"/>
    </operation>
    .
    .
    .
  <binding name="IOBISMSClientbinding" type="tns:IOBISMSClient">
    <soap:binding style="rpc"
transport="http://schemas.xmlsoap.org/soap/http"/>
    <operation name="CustomerFinancialGet">
      <soap:operation
soapAction="urn:uOBI_Intf-IOBISMSClient#CustomerFinancialGet" style="rpc"/>
      <input message="tns:CustomerFinancialGet2Request">
        <soap:body use="encoded"
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="urn:uOBI_Intf-IOBISMSClient"/>
        <soap:header xmlns:n1="http://schemas.xmlsoap.org/wsdl/"
n1:required="true" use="encoded"
message="tns:CustomerFinancialGet2headerRequest" part="TSecurity"
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="urn:uGlobalSOAPTypes"/>
      </input>
      <output message="tns:CustomerFinancialGet2Response">
        <soap:body use="encoded"
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="urn:uOBI_Intf-IOBISMSClient"/>
      </output>
    </operation>


Re: typeMapping and Bad Types

Posted by "Kevin J. Duling" <ja...@hotmail.com>.
I'm a little closer; I've found another piece of the puzzle.  I didn't
understand what "SAXException: Bad types (classA -> classB)" meant.  While
working on the server-side of my app, I created this same problem by
returning the wrong object type.  So I'm assuming this message is similar to
a ClassCastException.

In my own situation, I'm able to deserialize a TResult object when it is the
only object in the message.  But when two objects are there, deserialization
doesn't work.  I've also found when I return a TResult object and a second
object that's "nil", deserialization works.

What I don't understand is why deserializing the 2nd object doesn't work
even though my WSDL distintly says that a GetCustomerFinancialsResponse will
consist of both a TResult and a TCustomerFinancials.

I don't see any point where I load the WSDL in as a resource.  I've only
generated code with WSDL2Java.  Am I supposed to set the location of the
WSDL in the code somewhere?

Here are the relevant pieces from the WSDL:

  <message name="CustomerFinancialGet2Request">
    <part name="CustomerID" type="ns1:TCustomerID"/>
    <part name="CustomerFinancial" type="ns1:TCustomerFinancial"/>
  </message>
  <message name="CustomerFinancialGet2Response">
    <part name="CustomerFinancial" type="ns1:TCustomerFinancial"/>
    <part name="return" type="ns2:TResult"/>
  </message>
    .
    .
    .
<portType name="IOBISMSClient">
    <operation name="CustomerFinancialGet">
      <input message="tns:CustomerFinancialGet2Request"/>
      <output message="tns:CustomerFinancialGet2Response"/>
    </operation>
    .
    .
    .
  <binding name="IOBISMSClientbinding" type="tns:IOBISMSClient">
    <soap:binding style="rpc"
transport="http://schemas.xmlsoap.org/soap/http"/>
    <operation name="CustomerFinancialGet">
      <soap:operation
soapAction="urn:uOBI_Intf-IOBISMSClient#CustomerFinancialGet" style="rpc"/>
      <input message="tns:CustomerFinancialGet2Request">
        <soap:body use="encoded"
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="urn:uOBI_Intf-IOBISMSClient"/>
        <soap:header xmlns:n1="http://schemas.xmlsoap.org/wsdl/"
n1:required="true" use="encoded"
message="tns:CustomerFinancialGet2headerRequest" part="TSecurity"
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="urn:uGlobalSOAPTypes"/>
      </input>
      <output message="tns:CustomerFinancialGet2Response">
        <soap:body use="encoded"
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="urn:uOBI_Intf-IOBISMSClient"/>
      </output>
    </operation>


Server without tomcat?

Posted by "Kevin J. Duling" <ja...@hotmail.com>.
Is there a way I can hook into the Axis classes from a String?  I'm having 
to retrofit some old software with my new service.  This release of my 
company's product is locked into an ancient version of Tomcat that isn't 
compatible with Axis.  Thankfully, it's a one-off and I can use Tomcat 4 in 
the current dev tree.  But for now, I'm tomcat-less.

Most of the other interfaces I've done have been HTTP encapsulated XML, so 
I'm able to grab the incoming request and store the body of the HTTP message 
in a String or build a org.w3c.dom.Document out of it.  Is there a way I can 
then push that into the SOAP classes for parsing and building the reply?  I 
also need to know how to pull the text of the SOAP envelop to send it back. 
I've been reading over the javadoc and Axis manual, but I haven't found 
anything yet that shows me how to do this.

typeMapping and Bad Types

Posted by "Kevin J. Duling" <ja...@hotmail.com>.
Help!  I've spent the day searching the archives and googling for "bad 
types", "beanMapping" and "typeMapping", but I'm still stuck. 
Deserialization of primitives and simple objects is working fine.  Complex 
objects are failing even with typeMapping elements in my client-config.wsdd.

The project I'm working on is a billing interface for a Video on Demand 
system.  When I send in my purchase object, I get back a TResult object 
which consisists of a return code (int) and errorText (String). 
Deserialization of this object works flawlessly.

But when making a query to find out how much available credit a customer has 
I get back both a TResult and a complex type of a TCustomerFinancial (see 
SOAP response below).  It contains an array object called TMetadataList.  So 
I thought I needed to add the following to my client-config.wsdd:

 <typeMapping qname="ns:TMetadataList" xmlns:ns="urn:GlobalSOAPTyes" 
type="java:com.ncube.vod.bps.billing.obi.TMetadata[]"
      serializer="org.apache.axis.encoding.ser.ArraySerializerFactory"
      deserializer="org.apache.axis.encoding.ser.ArrayDeserializerFactory" 
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>


This hasn't had any effect.  I still receive the dreaded "Bad types" 
exception:

Nov 11, 2004 2:31:56 PM org.apache.axis.client.Call invoke
SEVERE: Exception:
org.xml.sax.SAXException: Bad types (class 
com.ncube.vod.bps.billing.obi.TCustomerFinancial -> class 
com.ncube.vod.bps.billing.obi.TResult)
        at 
org.apache.axis.message.RPCHandler.onStartChild(RPCHandler.java:282)
        at 
org.apache.axis.encoding.DeserializationContext.startElement(DeserializationContext.java:1025)
        at 
org.apache.axis.message.SAX2EventRecorder.replay(SAX2EventRecorder.java:159)
        at 
org.apache.axis.message.MessageElement.publishToHandler(MessageElement.java:1138)
        at 
org.apache.axis.message.RPCElement.deserialize(RPCElement.java:308)
        at org.apache.axis.message.RPCElement.getParams(RPCElement.java:342)
        at org.apache.axis.client.Call.invoke(Call.java:2420)
        at org.apache.axis.client.Call.invoke(Call.java:2319)
        at org.apache.axis.client.Call.invoke(Call.java:1776)
        at 
com.ncube.vod.bps.billing.obi.IOBISMSClientbindingStub.customerFinancialGet(IOBISMSClientbindingStub.java:524)
        at 
com.ncube.vod.bps.billing.OBIClient.parseBalanceRequest(OBIClient.java:153)
        at 
com.ncube.vod.bps.billing.BillService.parseXML(BillService.java:124)
        at 
com.ncube.vod.bps.ops.BillingOp.initialHandleNote(BillingOp.java:407)
        at 
com.ncube.vod.bps.ops.BillingOp.processNotification(BillingOp.java:214)
        at 
com.ncube.vod.operation.OpsCenter.processNotification(OpsCenter.java:258)
        at 
com.ncube.vod.istruct.Filter.processNetworkMessage(Filter.java:148)
        at 
com.ncube.vod.istruct.QManager$FilterThread.run(QManager.java:250)

The WSDL defines TCustomerFinancial as:

      <xs:complexType name="TCustomerFinancial">
        <xs:sequence>
          <xs:element name="RemainingCreditLimit" type="xs:double"/>
          <xs:element name="CurrentBalance" type="xs:double"/>
          <xs:element name="MonthlyCreditLimit" type="xs:double"/>
          <xs:element name="LastBillAmt" type="xs:double"/>
          <xs:element name="LastBillDate" type="xs:dateTime"/>
          <xs:element name="LastCycleCloseDate" type="xs:dateTime"/>
          <xs:element name="LastPaymentAmt" type="xs:double"/>
          <xs:element name="LastPaymentDate" type="xs:dateTime"/>
          <xs:element name="TotalBalanceDue" type="xs:double"/>
          <xs:element name="Due30" type="xs:double"/>
          <xs:element name="Due60" type="xs:double"/>
          <xs:element name="Due90" type="xs:double"/>
          <xs:element name="Due120" type="xs:double"/>
          <xs:element name="MetadataList" type="ns2:TMetadataList"/>
        </xs:sequence>

And TMetadataList is defined:

    <xs:schema targetNamespace="urn:uGlobalSOAPTypes" 
xmlns="urn:uGlobalSOAPTypes">
      <xs:complexType name="TMetadataList">
        <xs:complexContent>
          <xs:restriction base="soapenc:Array">
            <xs:sequence/>
            <xs:attribute ref="soapenc:arrayType" 
n1:arrayType="ns2:TMetadata[]" xmlns:n1="http://schemas.xmlsoap.org/wsdl/"/>
          </xs:restriction>
        </xs:complexContent>

TMetatdata itself is:

      <xs:complexType name="TMetadata">
        <xs:sequence>
          <xs:element name="Tag" type="xs:string"/>
          <xs:element name="Value" type="xs:anyType"/>
        </xs:sequence>
      </xs:complexType>

The response from the SOAP server is:

HTTP/1.1 200 OK
Connection: keep-alive
Content-Type: text/xml
Content-Length: 1543
Server: Indy/9.0.11

<?xml version="1.0" encoding="UTF-8"?>
   <SOAP-ENV:Envelope 
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
      <SOAP-ENV:Body 
SOAP-ENC:encodingStyle="http://schemas.xmlsoap.org/soap/envelope/">
         <NS1:CustomerFinancialGetResponse 
xmlns:NS1="urn:uOBI_Intf-IOBISMSClient" xmlns:NS2="urn:uGlobalSOAPTypes" 
xmlns:NS3="urn:uOBI_Intf">
            <NS2:TResult id="1" xsi:type="NS2:TResult">
               <ResultCode xsi:type="xsd:int">0</ResultCode>
               <ResultText xsi:type="xsd:string">OK</ResultText>
            </NS2:TResult>
            <return href="#1"/>
            <NS3:TCustomerFinancial id="2" 
xsi:type="NS3:TCustomerFinancial">
               <RemainingCreditLimit 
xsi:type="xsd:double">199.99</RemainingCreditLimit>
               <CurrentBalance xsi:type="xsd:double">0</CurrentBalance>
               <MonthlyCreditLimit 
xsi:type="xsd:double">0</MonthlyCreditLimit>
               <LastBillAmt xsi:type="xsd:double">0</LastBillAmt>
               <LastBillDate xsi:nil="true"/>
               <LastCycleCloseDate xsi:nil="true"/>
               <LastPaymentAmt xsi:type="xsd:double">0</LastPaymentAmt>
               <LastPaymentDate xsi:nil="true"/>
               <TotalBalanceDue xsi:type="xsd:double">0</TotalBalanceDue>
               <Due30 xsi:type="xsd:double">0</Due30>
               <Due60 xsi:type="xsd:double">0</Due60>
               <Due90 xsi:type="xsd:double">0</Due90>
               <Due120 xsi:type="xsd:double">0</Due120>
               <MetadataList xsi:type="SOAP-ENC:Array" 
SOAP-ENC:arrayType="NS2:TMetadata[0]"/>
            </NS3:TCustomerFinancial>
            <CustomerFinancial href="#2"/>
         </NS1:CustomerFinancialGetResponse>
      </SOAP-ENV:Body>
   </SOAP-ENV:Envelope>