You are viewing a plain text version of this content. The canonical link for it is here.
Posted to soap-user@ws.apache.org by Nige White <ni...@forward-comp.co.uk> on 2004/11/18 16:33:25 UTC

Adding a deserializer for a new type

Scott, and other listmembers,

First of all, thanks for all your help so far. I have the system 
working, and my new SOAP-based java proxy object slots into the web app 
where the old proprietary one used to go easily (I generate it with 
exactly the same signature). With compression, packets are ~35% of their 
full size...

Now I want to encode some returning binary data from my DBL server as a 
hex string. so a

record
    a   ,[3]i1, 1, 2, 3

which is how you declare a 3 byte array with initial values in DBL will 
become

<?xml version='1.0' encoding='ISO-8859-1'?>
<SOAP-ENV:Envelope
 xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
 xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
 xmlns:xsd="http://www.w3.org/1999/XMLSchema"
 xmlns:xse="http://schemas.xmlsoap.org/soap/encoding/"
 xmlns:fcl="urn:forward-comp.co.uk">
<SOAP-ENV:Body>
<fcl:methodNameResponse 
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<return xsi:type="xse:int">1</return>
<paramname xsi:type="fcl:hexString">000102</paramname>
</fcl:methodNameResponse>
<SOAP-ENV:Body>
</SOAP-ENV:Envelope>

How can I register a Deserializer so that this is deserialized into a 
StringBuffer?

I have written a Deserializer class (HexStringDeserializer) which uses 
DomUtils to get the childCharacterData from the Element, parses out the 
hex pairs, and returns the Bean - it's based on the default SOAP 
StringSerializer.

How do I *register" that class so that when SOAP sees the above XML, it 
calls my class?

I'm doing this because I'm concerned about the performance of SOAP's 
Base64 class. Well, I'm concerned about the performance of SOAP. It 
takes much longer to marshall and unmarshall the parameters than the 
previous proprietary RPC protocol. I've written a lightweight 
BeanSerializer class which does it's own introspection just using Class 
and Method - avioding the java.beans package (it caches Collections of 
getter and setter methods in HashMaps keyed by the Class of the bean). 
This is faster than the SOAP one, but the overall performance of the 
client is still slow.

Tailing the log file on my server, it moves in jerks. The Envelopes 
arrive, are processed and and Envelope is sent back all in one rush. 
Then there's a definite pause before the new request from the SOAP 
client comes in. The bottleneck is on the client side, and I suspect 
it's the complex marshalling/unmarshalling.

I do a subjective test where I download an 800K BMP. The old web app 
gets it in a couple of seconds, the new SOAP-based one edges up the 
screen like a 3600 baud modem I'll never sell that to the boss!

Well, anyway, thanks for any help,

Nigel

_____________________________________________________________________
This message has been checked for all known viruses. Virus scanning
powered by Messagelabs http://www.messagelabs.com For more information
e-mail : hostmaster@forward-comp.co.uk



Re: Adding a deserializer for a new type

Posted by Scott Nichol <sn...@scottnichol.com>.
Correction:

 <return xsi:type="fc1:methodNameReturn">
   <returnvalue xsi:type="xsd:int">1</returnvalue>
   <paramname xsi:type="xsd:hexBinary">000102</paramname>
 </return>

Scott Nichol

Do not send e-mail directly to this e-mail address,
because it is filtered to accept only mail from
specific mail lists.
----- Original Message ----- 
From: "Scott Nichol" <sn...@scottnichol.com>
To: <so...@ws.apache.org>
Sent: Thursday, November 18, 2004 10:50 AM
Subject: Re: Adding a deserializer for a new type


In this specific case, use the xsd:hexBinary type, and Apache SOAP can deserialize it "automatically".

 <paramname xsi:type="xsd:hexBinary">000102</paramname>

However, I must point out that your SOAP payload below has a return value and output parameters.  Apache SOAP does not handle output parameters.  You must return a single value.  For example, you could have

 <return xsi:type="fc1:methodNameReturn">
   <returnvalue xsi:type="xse:int">1</returnvalue>
   <paramname xsi:type="fcl:hexString">000102</paramname>
 </return>

This returns to the discussion of how to register a deserializer on the Java client so it can handle this new return type "fc1:methodNameReturn".  The easiest way it to use the BeanSerializer included with Apache SOAP.

First, define the class into which to deserialize

public class MethodNameReturn {
    public int returnvalue;
    public byte[] paramname;
}

Then, in your client code, add the deserializer to your mappings (before you "call"):

    SOAPMappingRegistry smr = new SOAPMappingRegistry();
    BeanSerializer beanSer = new BeanSerializer();

    // Map the types.
    smr.mapTypes(Constants.NS_URI_SOAP_ENC,
                 new QName("urn:forward-comp.co.uk", "methodNameReturn"),
                 MethodNameReturn.class, beanSer, beanSer);

    // Build the call.
    Call call = new Call();
    call.setSOAPMappingRegistry(smr);

Note that I have lifted this code from the samples that come with Apache SOAP.  They are worth looking at to see the patterns of usage and specific variations.

Scott Nichol

Do not send e-mail directly to this e-mail address,
because it is filtered to accept only mail from
specific mail lists.
----- Original Message ----- 
From: "Nige White" <ni...@forward-comp.co.uk>
To: <so...@ws.apache.org>
Sent: Thursday, November 18, 2004 10:33 AM
Subject: Adding a deserializer for a new type


> Scott, and other listmembers,
> 
> First of all, thanks for all your help so far. I have the system 
> working, and my new SOAP-based java proxy object slots into the web app 
> where the old proprietary one used to go easily (I generate it with 
> exactly the same signature). With compression, packets are ~35% of their 
> full size...
> 
> Now I want to encode some returning binary data from my DBL server as a 
> hex string. so a
> 
> record
>     a   ,[3]i1, 1, 2, 3
> 
> which is how you declare a 3 byte array with initial values in DBL will 
> become
> 
> <?xml version='1.0' encoding='ISO-8859-1'?>
> <SOAP-ENV:Envelope
>  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
>  xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
>  xmlns:xsd="http://www.w3.org/1999/XMLSchema"
>  xmlns:xse="http://schemas.xmlsoap.org/soap/encoding/"
>  xmlns:fcl="urn:forward-comp.co.uk">
> <SOAP-ENV:Body>
> <fcl:methodNameResponse 
> SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
> <return xsi:type="xse:int">1</return>
> <paramname xsi:type="fcl:hexString">000102</paramname>
> </fcl:methodNameResponse>
> <SOAP-ENV:Body>
> </SOAP-ENV:Envelope>
> 
> How can I register a Deserializer so that this is deserialized into a 
> StringBuffer?
> 
> I have written a Deserializer class (HexStringDeserializer) which uses 
> DomUtils to get the childCharacterData from the Element, parses out the 
> hex pairs, and returns the Bean - it's based on the default SOAP 
> StringSerializer.
> 
> How do I *register" that class so that when SOAP sees the above XML, it 
> calls my class?
> 
> I'm doing this because I'm concerned about the performance of SOAP's 
> Base64 class. Well, I'm concerned about the performance of SOAP. It 
> takes much longer to marshall and unmarshall the parameters than the 
> previous proprietary RPC protocol. I've written a lightweight 
> BeanSerializer class which does it's own introspection just using Class 
> and Method - avioding the java.beans package (it caches Collections of 
> getter and setter methods in HashMaps keyed by the Class of the bean). 
> This is faster than the SOAP one, but the overall performance of the 
> client is still slow.
> 
> Tailing the log file on my server, it moves in jerks. The Envelopes 
> arrive, are processed and and Envelope is sent back all in one rush. 
> Then there's a definite pause before the new request from the SOAP 
> client comes in. The bottleneck is on the client side, and I suspect 
> it's the complex marshalling/unmarshalling.
> 
> I do a subjective test where I download an 800K BMP. The old web app 
> gets it in a couple of seconds, the new SOAP-based one edges up the 
> screen like a 3600 baud modem I'll never sell that to the boss!
> 
> Well, anyway, thanks for any help,
> 
> Nigel
> 
> _____________________________________________________________________
> This message has been checked for all known viruses. Virus scanning
> powered by Messagelabs http://www.messagelabs.com For more information
> e-mail : hostmaster@forward-comp.co.uk
> 
> 
> 


Re: Adding a deserializer for a new type

Posted by Scott Nichol <sn...@scottnichol.com>.
In this specific case, use the xsd:hexBinary type, and Apache SOAP can deserialize it "automatically".

 <paramname xsi:type="xsd:hexBinary">000102</paramname>

However, I must point out that your SOAP payload below has a return value and output parameters.  Apache SOAP does not handle output parameters.  You must return a single value.  For example, you could have

 <return xsi:type="fc1:methodNameReturn">
   <returnvalue xsi:type="xse:int">1</returnvalue>
   <paramname xsi:type="fcl:hexString">000102</paramname>
 </return>

This returns to the discussion of how to register a deserializer on the Java client so it can handle this new return type "fc1:methodNameReturn".  The easiest way it to use the BeanSerializer included with Apache SOAP.

First, define the class into which to deserialize

public class MethodNameReturn {
    public int returnvalue;
    public byte[] paramname;
}

Then, in your client code, add the deserializer to your mappings (before you "call"):

    SOAPMappingRegistry smr = new SOAPMappingRegistry();
    BeanSerializer beanSer = new BeanSerializer();

    // Map the types.
    smr.mapTypes(Constants.NS_URI_SOAP_ENC,
                 new QName("urn:forward-comp.co.uk", "methodNameReturn"),
                 MethodNameReturn.class, beanSer, beanSer);

    // Build the call.
    Call call = new Call();
    call.setSOAPMappingRegistry(smr);

Note that I have lifted this code from the samples that come with Apache SOAP.  They are worth looking at to see the patterns of usage and specific variations.

Scott Nichol

Do not send e-mail directly to this e-mail address,
because it is filtered to accept only mail from
specific mail lists.
----- Original Message ----- 
From: "Nige White" <ni...@forward-comp.co.uk>
To: <so...@ws.apache.org>
Sent: Thursday, November 18, 2004 10:33 AM
Subject: Adding a deserializer for a new type


> Scott, and other listmembers,
> 
> First of all, thanks for all your help so far. I have the system 
> working, and my new SOAP-based java proxy object slots into the web app 
> where the old proprietary one used to go easily (I generate it with 
> exactly the same signature). With compression, packets are ~35% of their 
> full size...
> 
> Now I want to encode some returning binary data from my DBL server as a 
> hex string. so a
> 
> record
>     a   ,[3]i1, 1, 2, 3
> 
> which is how you declare a 3 byte array with initial values in DBL will 
> become
> 
> <?xml version='1.0' encoding='ISO-8859-1'?>
> <SOAP-ENV:Envelope
>  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
>  xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
>  xmlns:xsd="http://www.w3.org/1999/XMLSchema"
>  xmlns:xse="http://schemas.xmlsoap.org/soap/encoding/"
>  xmlns:fcl="urn:forward-comp.co.uk">
> <SOAP-ENV:Body>
> <fcl:methodNameResponse 
> SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
> <return xsi:type="xse:int">1</return>
> <paramname xsi:type="fcl:hexString">000102</paramname>
> </fcl:methodNameResponse>
> <SOAP-ENV:Body>
> </SOAP-ENV:Envelope>
> 
> How can I register a Deserializer so that this is deserialized into a 
> StringBuffer?
> 
> I have written a Deserializer class (HexStringDeserializer) which uses 
> DomUtils to get the childCharacterData from the Element, parses out the 
> hex pairs, and returns the Bean - it's based on the default SOAP 
> StringSerializer.
> 
> How do I *register" that class so that when SOAP sees the above XML, it 
> calls my class?
> 
> I'm doing this because I'm concerned about the performance of SOAP's 
> Base64 class. Well, I'm concerned about the performance of SOAP. It 
> takes much longer to marshall and unmarshall the parameters than the 
> previous proprietary RPC protocol. I've written a lightweight 
> BeanSerializer class which does it's own introspection just using Class 
> and Method - avioding the java.beans package (it caches Collections of 
> getter and setter methods in HashMaps keyed by the Class of the bean). 
> This is faster than the SOAP one, but the overall performance of the 
> client is still slow.
> 
> Tailing the log file on my server, it moves in jerks. The Envelopes 
> arrive, are processed and and Envelope is sent back all in one rush. 
> Then there's a definite pause before the new request from the SOAP 
> client comes in. The bottleneck is on the client side, and I suspect 
> it's the complex marshalling/unmarshalling.
> 
> I do a subjective test where I download an 800K BMP. The old web app 
> gets it in a couple of seconds, the new SOAP-based one edges up the 
> screen like a 3600 baud modem I'll never sell that to the boss!
> 
> Well, anyway, thanks for any help,
> 
> Nigel
> 
> _____________________________________________________________________
> This message has been checked for all known viruses. Virus scanning
> powered by Messagelabs http://www.messagelabs.com For more information
> e-mail : hostmaster@forward-comp.co.uk
> 
> 
>