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 Michael Thome <mt...@bbn.com> on 2005/03/08 22:33:05 UTC
Stupid question: how to deserialize/serialize axis data objects
Here's a stupid question - gotta be a faq, but darned if I can find the
right keywords...
I'd like to be able to deserialize/serialize data in the form of
wsdl2java-generated structures from/to arbitrary streams. For instance,
if I serialize such an object to a file, I would like to end up with an
xml representation of the object in the file that conforms to the schema
I used to generate the data structures.
I currently have a glacially-slow hack for deserialization involving
setting up a dummy DeserializationContext and calling parse... but it is
*horrendously* slow, seeming to spend all its time creating and
releasing thousands of temporary Documents... I'm clearly missing
something here.
Thanks for any help,
-Michael
Re: Stupid question: how to deserialize/serialize axis data objects
Posted by Michael Thome <mt...@bbn.com>.
I've made some progress on my own worth mentioning...
It turns out that the feature of my data that was causing axis so much
trouble was the rather deep xml structure passed around by my schema
(using xsd:any ##any): NodeImpl.getOwnerDocument has spectacularly bad
behavior on deep structures.
I've submitted a patch attached to jira (
http://issues.apache.org/jira/browse/AXIS-1862 ) that fixes this issue.
Along the way, I stumbled on an alternative implementation of
deserialize that performed much better than either your or my original
code... at least, until I fixed the NodeImpl performance bug.
Essentially, I do the following:
String mstr = ... // the message;
Message m = new Message(mstr,true);
m.setMessageContext(new MessageContext(new
org.apache.axis.server.AxisServer()));
javax.xml.soap.SOAPPart part = m.getSOAPPart();
SOAPEnvelope e = (SOAPEnvelope) part.getEnvelope();
SOAPBodyElement be = e.getFirstBody();
MessageElement mel = findFirstArgument(be);
Object result = mel.getValueAsType(myqn, myclass);
I found the basic structure in the axis unit test code. Before I fixed
the NodeImpl algorithm, this was around 100x faster than the approaches
I tried before.
At any rate, using either the above code or my original code leaves me
deserializing a bit more than 1000x faster than yesterday. Can't
complain too much about that... ;-)
Thanks,
-Michael
Michael Thome wrote:
> Thanks for the examples. I've got a few followups, if you don't mind...
>
> Peter Molettiere wrote:
>
>>
>> Chances are you're doing it right. My experience is that axis is
>> pretty slow, especially if you have large object graphs to read and
>> write.
>
>
> I sure hope I'm not doing it right, though so far your solution and
> mine performs about the same... that is, unacceptably slow by several
> orders of magnitude - 4 minutes to deserialize a 1KB serialized message!
>
>
Re: Stupid question: how to deserialize/serialize axis data objects
Posted by Michael Thome <mt...@bbn.com>.
Thanks for the examples. I've got a few followups, if you don't mind...
Peter Molettiere wrote:
>
> Chances are you're doing it right. My experience is that axis is
> pretty slow, especially if you have large object graphs to read and
> write.
I sure hope I'm not doing it right, though so far your solution and mine
performs about the same... that is, unacceptably slow by several orders
of magnitude - 4 minutes to deserialize a 1KB serialized message!
> These two methods depend on the following code to register the object
> types you'd like to serialize first:
I presume that these are filling up static structures referenced by the
service instance? Or is there something missing that links the service
to the AxisServer parameter?
Could mis-registration of the types lead to poor performance somehow, or
would it just plain fail?
Thanks much,
-Michael
Re: Stupid question: how to deserialize/serialize axis data objects
Posted by Peter Molettiere <pi...@axonstudios.net>.
On Mar 8, 2005, at 1:33 PM, Michael Thome wrote:
> I'd like to be able to deserialize/serialize data in the form of
> wsdl2java-generated structures from/to arbitrary streams. For
> instance, if I serialize such an object to a file, I would like to end
> up with an xml representation of the object in the file that conforms
> to the schema I used to generate the data structures.
>
> I currently have a glacially-slow hack for deserialization involving
> setting up a dummy DeserializationContext and calling parse... but it
> is *horrendously* slow, seeming to spend all its time creating and
> releasing thousands of temporary Documents... I'm clearly missing
> something here.
Chances are you're doing it right. My experience is that axis is pretty
slow, especially if you have large object graphs to read and write.
Here's some code you look at to see if it helps. This is posted as part
of a bug I opened dealing with large amounts of memory being used and
released during the ser/deser process. It hasn't really been fixed
aside from a few small patches which help a little.
You can look here for complete compilable code:
http://issues.apache.org/jira/browse/AXIS-1771
These two methods depend on the following code to register the object
types you'd like to serialize first:
...
ServiceFactory serviceFactory = null;
Service service = null;
try {
serviceFactory = ServiceFactory.newInstance();
service = serviceFactory.createService(new QName(endpoint,
"MemoryTester"));
} catch (ServiceException e) {
e.printStackTrace();
return;
}
TypeMappingRegistry registry = service.getTypeMappingRegistry();
TypeMapping map = registry.getDefaultTypeMapping();
map.register(Entity.class, qnEntity,
new
org.apache.axis.encoding.ser.BeanSerializerFactory(Entity.class,
qnEntity),
new
org.apache.axis.encoding.ser.BeanDeserializerFactory(Entity.class,
qnEntity)
);
....
Note that in this method you can swap out the StringWriter for a
FileWriter to write to files:
public String serialize( QName dataQName, Object data ) throws
Exception {
AxisServer server = new AxisServer();
server.setOption(AxisEngine.PROP_DOMULTIREFS, Boolean.TRUE);
MessageContext msgContext = new MessageContext(server);
msgContext.setProperty(AxisEngine.PROP_DOMULTIREFS,
Boolean.TRUE);
SOAPEnvelope msg = new SOAPEnvelope();
RPCParam arg = new RPCParam("Test", "struct", data);
RPCElement body = new RPCElement("Test", "method1", new
Object[]{arg});
msg.addBodyElement(body);
StringWriter writer = new StringWriter();
SerializationContext context = new SerializationContext(writer,
msgContext);
msg.output(context);
String messageStr = writer.toString();
return messageStr;
}
Here again you can swap out the StringReader for a FileReader:
public Object deserialize( String messageStr ) throws Exception {
AxisServer server = new AxisServer();
server.setOption(AxisEngine.PROP_DOMULTIREFS, Boolean.TRUE);
MessageContext msgContext = new MessageContext(server);
msgContext.setProperty(AxisEngine.PROP_DOMULTIREFS,
Boolean.TRUE);
//System.err.println(messageStr);
Reader reader = new StringReader(messageStr);
DeserializationContext dser = new DeserializationContext
(new InputSource(reader), msgContext,
org.apache.axis.Message.REQUEST);
dser.parse();
SOAPEnvelope env = dser.getEnvelope();
RPCElement rpcElem = (RPCElement) env.getFirstBody();
MessageElement struct = rpcElem.getChildElement(new
QName("Test", "struct"));
Object result = struct.getObjectValue();
return result;
}
--
Peter Molettiere
Senior Engineer
Truereq, Inc.
http://www.truereq.com/