Right now, it will fail because [de-]serializers are found by exact type
match only (or a default if one is defined, but this is typically
useless).  I did not take the time to change the [de-]serializer lookup,
because I am not sure what the right way is to implement polymorphic
return values.

One issue is, how will a client know what different types it can receive
if the return value is polymorphic?  In your example, a client who
thinks the contract is A getA() may always expect to deserialize an A.
Receiving a B would be an error: the client does not even know what a B
is!  This is a place where WSDL would be a big help.

You have raised the other major issue: should the service have to map
all of the concrete types that may be returned?

I am thinking that to address the first issue, I should make return
value polymorphism an option in the deployment descriptor, so that the
service implementor will have to explicitly enable it for the service.
It would then be up to the implementor to document the possible return
types for client implementors.

For the second issue, I would walk the inheritance chain looking for a
serializer, then check implemented interfaces for one.  This really is
not too big of a deal.

Scott Nichol

----- Original Message -----
From: "Alex Dovlecel" <[EMAIL PROTECTED]>
To: <[EMAIL PROTECTED]>
Sent: Wednesday, December 04, 2002 9:42 AM
Subject: Re: passing interfaces instead of classes


> Have some questions about it (I have not read the changed code).
>
> If I have a method with the following signature:
>
> A getA ( ) ;
>
> and B extends A.
>
> I have mapped the A class into the SOAP engine, but the B class is not
mapped
> (no QName and serializer associated).
>
> If the getA( ) will return a B, what SOAP will do ? Will fail because
could
> not find (de)serializer for type B, or will try to find the closest
mapped
> type and use the serializer for that type? (in that case, will
serialize the
> B as an A object)
>
> pls answer me,
> Tx
> dovle
>
>
> >
> > I have just committed a change so that the return value of a service
> > method is serialized using its actual class rather than its declared
> > one, assuming the declared one is not a primitive type.  This
feature
> > will be available in future nightly builds, which are accessed at
> > http://cvs.apache.org/dist/soap/nightly/.
> >
> > Scott Nichol
> >
> > ----- Original Message -----
> > From: "Scott Nichol" <[EMAIL PROTECTED]>
> > To: <[EMAIL PROTECTED]>
> > Sent: Monday, December 02, 2002 5:12 PM
> > Subject: Re: passing interfaces instead of classes
> >
> > > Without looking at the code, my guess would be that Apache SOAP
> > > serializes the return value based on the declared type of the
> >
> > function,
> >
> > > not the actual type returned.  I will have to look at this later.
> > >
> > > Scott Nichol
> > >
> > > ----- Original Message -----
> > > From: "Chris Kelly" <[EMAIL PROTECTED]>
> > > To: <[EMAIL PROTECTED]>
> > > Sent: Monday, December 02, 2002 5:26 PM
> > > Subject: Re: passing interfaces instead of classes
> > >
> > > > The problem I had is that my service actually looks like this:
> > > >
> > > >  class SoapService {
> > > >    public IData doSomething( IData data ) {...}
> > > >  }
> > > >
> > > > When I tried to send a ComplexData or SimpleData concrete class
> >
> > back,
> >
> > > it
> > >
> > > > didn't work. Are you saying that was just a config or similar
> >
> > problem?
> >
> > > > Currently, I use a return type mapping when one of the service
> >
> > methods
> >
> > > > returns an array. Do I need to set up a return type mapping, as
> >
> > shown
> >
> > > in
> > >
> > > > the following code, or will the return be handled automatically
and
> >
> > I
> >
> > > just
> > >
> > > > had something set wrong?
> > > >
> > > > SOAPMappingRegistry smr;
> > > > ...
> > > > smr.mapTypes(
> > > >   Constants.NS_URI_SOAP_ENC,
> > > >   new QName( uri, "return" ),
> > > >   null,
> > > >   ???, ??? );
> > > > ...
> > > > call.setSOAPMappingRegistry( smr );
> > > >
> > > > At 09:09 AM 12/2/02 -0500, Scott Nichol wrote:
> > > > >It is up to you when you define your mappings and/or write your
> > > > >serializers whether the classes implementing interfaces will be
> > > > >serialized with just information for the interface or for the
> >
> > actual
> >
> > > > >class.  I personally prefer to have separate mappings for each
> > >
> > > concrete
> > >
> > > > >class.  I don't like to have one serializer for an interface
that
> > > > >internally actually knows how to serialize each class that
> >
> > implements
> >
> > > > >the interface.  Big switch statements or multiple if/else
branches
> > >
> > > don't
> > >
> > > > >feel right to me in the O-O world.
> > > > >
> > > > >Anyway, in your case this means I would write serializers (and
> > > > >deserializers) for SimpleData and ComplexData, then map each
type
> >
> > to
> >
> > > the
> > >
> > > > >corresponding [de-]serializer.  The server will correctly
resolve
> > >
> > > these
> > >
> > > > >types as parameters to the doSomething method.
> > > > >
> > > > >----- Original Message -----
> > > > >From: "Chris Kelly" <[EMAIL PROTECTED]>
> > > > >To: <[EMAIL PROTECTED]>
> > > > >Sent: Sunday, December 01, 2002 7:48 PM
> > > > >Subject: passing interfaces instead of classes
> > > > >
> > > > >> Consider:
> > > > >>
> > > > >> interface IData {
> > > > >>   int getValue();
> > > > >> }
> > > > >>
> > > > >> class SimpleData implements IData {
> > > > >>   int value;
> > > > >>   public SimpleData( int v ) { value = v; }
> > > > >>   public int getValue() { return value; }
> > > > >> }
> > > > >>
> > > > >> class ComplexData implements IData {
> > > > >>   float value, multiplier;
> > > > >>   public SimpleData( float v, float m; ) {
> > > > >>     value = v;
> > > > >>     multiplier = m;
> > > > >>   }
> > > > >>   public int getValue() {
> > > > >>     return (int) ( multiplier * value );
> > > > >>   }
> > > > >> }
> > > > >>
> > > > >> Then, consider a service that accepts an IData object:
> > > > >>
> > > > >> class SoapService {
> > > > >>   public doSomething( IData data ) {...}
> > > > >> }
> > > > >>
> > > > >> If I pass an IData object in a bean-like fashion, only the
> >
> > 'value'
> >
> > > > >will be
> > > > >
> > > > >> sent in the XML, not the 'multiplier' if the IData object I'm
> > >
> > > sending
> > >
> > > > >is a
> > > > >
> > > > >> ComplexData object.
> > > > >>
> > > > >> If I change SoapService.doSomething to accept either a
SimpleData
> > >
> > > or a
> > >
> > > > >> ComplexData, then the other class can't be sent.
> > > > >>
> > > > >> So, am I missing something, or is it difficult to represent
> >
> > passed
> >
> > > > >objects
> > > > >
> > > > >> as interfaces? Must they be represented as classes?
> > > > >>
> > > > >> One way around this would be to pass IData objects as the
name in
> > >
> > > the
> > >
> > > > >XML,
> > > > >
> > > > >> and include the name of the implementing class in the XML as
> >
> > well.
> >
> > > An
> > >
> > > > >IData
> > > > >
> > > > >> de/serializer would then determine the implementing class,
and
> >
> > call
> >
> > > a
> > >
> > > > >> de/serializer specific to that implementing class. Is there
an
> > > > >
> > > > >automatic
> > > > >
> > > > >> way to do this?
> > > > >>
> > > > >>
> > > > >> --
> > > > >> To unsubscribe, e-mail:
> > > > >
> > > > ><mailto:[EMAIL PROTECTED]>
> > > > >
> > > > >> For additional commands, e-mail:
> > > > >
> > > > ><mailto:[EMAIL PROTECTED]>
> > > > >
> > > > >
> > > > >
> > > > >
> > > > >--
> > > > >To unsubscribe, e-mail:
> > >
> > > <mailto:[EMAIL PROTECTED]>
> > >
> > > > >For additional commands, e-mail:
> > >
> > > <mailto:[EMAIL PROTECTED]>
> > >
> > > > --
> > > > To unsubscribe, e-mail:
> > >
> > > <mailto:[EMAIL PROTECTED]>
> > >
> > > > For additional commands, e-mail:
> > >
> > > <mailto:[EMAIL PROTECTED]>
> > >
> > >
> > >
> > >
> > > --
> > > To unsubscribe, e-mail:
> >
> > <mailto:[EMAIL PROTECTED]>
> >
> > > For additional commands, e-mail:
> >
> > <mailto:[EMAIL PROTECTED]>
>
> --
> To unsubscribe, e-mail:
<mailto:[EMAIL PROTECTED]>
> For additional commands, e-mail:
<mailto:[EMAIL PROTECTED]>
>
>


--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to