Nitin has posted 391 posts at DZone. View Full User Profile

Automatic serialization of ActionScript objects to and from XML

04.23.2009
| 20882 views |
  • submit to reddit

In Flex applications that use a backend server for data manipulation and storage, serializing and transferring the objects from one layer to another is an important matter. In this short tip, Constantin Moldovanu shows you how to automatically serialize objects from XML to ActionScript and vice versa and how BlazeDS and LiveCycle Data Services can effectively hide this step for the developer.

By Constantin Moldovanu 

Sometimes it is not possible to use AMF and remoting and we have to rely on XML or JSON for transporting the objects. In this case an automatic serialization from XML to ActionScript and vice versa would come in handy.

Suppose we have a Java EE backend server, that has some model classes that are exported to custom XML. What follows also applies to JSON:

The first idea would be to get the incoming XML, use the describeType() function and parse its output, cycle through the properties and assign them to a certain ActionScript object. The same could be achieved by directly parsing the incoming XML or by using the for..in construct. The generated ActionScript objects would, however, be typeless and thus the necessity to place in the incoming XML data some hint regarding the type of object that needs to be created.

At this point we can use registerClassAlias() in Flex or, more comfortably, the metadata [RemoteClass(alias="")] on top of each of the ActionScript domain classes. The AS classes will be, in this case, identical to the ones used with the remoting functionality, providing a decoupled way of serializing ActionScript objects.

The last step is building the converter class, that receives in input an XML and returns a strongly typed ActionScript object; this class will make use of getClassByAlias() to create the proper classes and fill them with the correct parameters.

Considering the case in which the Java server has a class Persona, with two properties nome and cognome, it can be exported into an XML that is similar to the following:

<?xml version="1.0" encoding="utf-8"?>
<object>
<nome>nome</nome>
<cognome>cognome</cognome>
<metadata>
<type>com.comtaste.model.Persona</type>
</metadata>
</object>

 

Note that we need a few naming conventions, such as the name of the root tag (in this example object) and an extra XML attribute, the metadata, which contains information about the identity of our remote object.

The target ActionScript class will simply be as if we were using it with remoting:

[RemoteClass(alias="com.comtaste.model.Persona")]
public class Persona {
public var nome:String;
public var cognome:String;
}

 

Note the RemoteAlias metadata, wich ensures that our class definition is registered with that alias. Inside the converter we will be able to say

var cls:Class = getClassByAlias("com.comtaste.model.Persona");
var output:Object = new cls();



and create an object of the correct ActionScript type Persona. This converter can be placed within a static function that can be called on the remote call result or inside a Cairngorm (or PureMVC) command. Using the latter approach we can benefit from the modularity these micro-architectures provide and only use the converter in few, well known, parts of the application.

The automatic converter can be written as in the following function:

public static function getObject(input:Object):* {
if ((input == null) || !input.hasOwnProperty("metadata"))
return input;

if (!input.metadata.hasOwnProperty("type"))
return input;
var cls:Class = getClassByAlias(input.metadata.type);
if (cls == null)
return input;

var output:Object = new cls();
for (var prop:Object in input) {
if (prop === "metadata")
continue;

if (input[prop] != null) {
if (input[prop].hasOwnProperty("object")) {
if (input[prop].object is ArrayCollection) {
output[prop] = new ArrayCollection();

for each (var o:Object in ArrayCollection(input[prop].object)) {
var newObj:* = getObject(o);
ArrayCollection(output[prop]).addItem(newObj);
}
} else {
output[prop] = getObject(input[prop].object);
}
} else {
output[prop] = input[prop];
}
}
}

return output;
}

This example considers the case of nested objects and uses our named convention for "object" and "metadata"; it obviously does not consider circular references. The drawback is that all of the ActionScript model classes have to be referenced in the main application at least once, so that the classes definitions would register their aliases safely.

 

References
Published at DZone with permission of its author, Nitin Bharti. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Javin Paul replied on Tue, 2011/04/19 - 10:12am

Nice article , you have indeed covered this topic in details. I have also blogged some of my experience as How Serialization works in Java  hope it would be useful.

Thanks
Javin

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.