JBoss.orgCommunity Documentation

Chapter 5. Marshalling

5.1. Mapping Your Domain
5.1.1. @Portable and @NonPortable
5.1.2. Manual Mapping
5.1.3. Manual Class Mapping
5.1.4. Custom Marshallers

Errai includes a comprehensive marshalling framework which permits the serialization of domain objects between the browser and the server. From the perspective of GWT, this is a complete replacement for the provided GWT serialization facilities and offers a great deal more flexibility. You are be able to map both application-specific domain model, as well as preexisting model, including model from third-party libraries using the custom definitions API.

All classes that you intend to be marshalled between the client and the server must be exposed to the marshalling framework. There are several ways you can do it and this section will take you through the different approaches you can take to fit your needs.

To make a Java class eligible for serialization with Errai Marshalling, mark it with the org.jboss.errai.common.client.api.annotations.Portable annotation. This tells the marshalling system to generate marshalling and demarshalling code for the annotated class and all of its nested classes.

The mapping strategy that will be used depends on how much information you provide about your model up-front. If you simply annotate a domain type with @Portable and do nothing else, the marshalling system will use and exhaustive strategy to determine how to construct and deconstruct instances of that type and its nested types.

The Errai marshalling system works by enumerating all of the Portable types it can find (by any of the three methods discussed in this section of the reference guide), eliminating all the non-portable types it can find (via @NonPortable annotations and entries in ErraiApp.properties ), then enumerating the marshallable properties that make up each remaining portable entity type. The rules that Errai uses for enumerating the properties of a portable entity type are as follows:

Note that the existence of methods called getFoo() , setFoo() , or both, does not mean that the entity has a property called foo . Errai Marshalling always works from fields when discovering properties.

When reading a field foo , Errai Marshalling will call the method getFoo() in preference to direct field access if the getFoo() method exists.

Similarly, when writing a field foo , Errai Marshalling will call the method setFoo() in preference to direct field access if the setFoo() method exists.

The above rules are sufficient for marshalling an existing entity to a JSON representation, but for de-marshalling, Errai must also know how to obtain an instance of a type. The rules that Errai uses for deciding how to create an instance of a @Portable type are as follows:

Now let's take a look at some common examples of how this works.

For types with a large number of optional attributes, a builder is often the best approach.

In this example, we have a nested Builder class that implements the Builder Pattern and calls the private Person constructor. Hand-written code will always use the builder to create Person instances, but the @MapsTo annotations on the private Person constructor tell Errai Marshalling to bypass the builder and construct instances of Person directly.

One final note: as a nested type of Person (which is marked @Portable ), the builder itself would normally be portable. However, we do not intend to move instances of Person.Builder across the network, so we mark Person.Builder as @NonPortable .

Some classes may be out of your control, making it impossible to annotate them for auto-discovery by the marshalling framework. For cases such as this, there are two approaches which can be undertaken to include these classes in your application.

The first approach is the easiest, but is contingent on whether or not the class is directly exposed to the GWT compiler. That means, the classes must be part of a GWT module and within the GWT client packages. See the GWT documentation on Client-Side Code for information on this.

The marshalling framework supports and promotes the concept of marshalling by interface contract, where possible. For instance, the framework ships with a marshaller which can marshall data to and from the java.util.List interface. Instead of having custom marshallers for classes such as ArrayList and LinkedList , by default, these implementations are merely aliased to the java.util.List marshaller.

There are two distinct ways to go about doing this. The most straightforward is to specify which marshaller to alias when declaring your class is @Portable .

In the case of this example, the marshaller will not attempt to comprehend your class. Instead, it will merely rely on the java.util.List marshaller to dematerialize and serialize instances of this type onto the wire.

If for some reason it is not feasible to annotate the class, directly, you may specify the mapping in the ErraiApp.properties file using the errai.marshalling.mappingAliases attribute.

The list of classes is whitespace-separated so that it may be split across lines.

The example above shows the equivalent mapping for the MyListImpl class from the previous example, as well as a mapping of a class to the java.util.Map marshaller.

The syntax of the mapping is as follows: <class_to_map> -> <contract_to_map_to> .

Although the default marshalling strategies in Errai Marshalling will suit the vast majority of use cases, there may be situations where it is necessary to manually map your classes into the marshalling framework to teach it how to construct and deconstruct your objects.

This is accomplished by specifying MappingDefinition classes which inform the framework exactly how to read and write state in the process of constructing and deconstructing objects.

All manual mappings should extend the org.jboss.errai.marshalling.rebind.api.model.MappingDefinition class. This is base metadata class which contains data on exactly how the marshaller can deconstruct and construct objects.

Consider the following class:

Let us construct this object like so:

It is clear that we may rely on this object's two getter methods to extract the totality of its state. But due to the fact that the mySuperName field is final, the only way to properly construct this object is to call its only public constructor and pass in the desired value of mySuperName .

Let us consider how we could go about telling the marshalling framework to pull this off:

And that's it. This describes to the marshalling framework how it should go about constructing and deconstructing MySuperCustomEntity .

Paying attention to our annotating comments, let's describe what we've done here.

There is another approach to extending the marshalling functionality that doesn't involve mapping rules, and that is to implement your own Marshaller class. This gives you complete control over the parsing and emission of the JSON structure.

The implementation of marshallers is made relatively straight forward by the fact that both the server and the client share the same JSON parsing API.

Consider the included java.util.Date marshaller that comes built-in to the marshalling framework:


The class is annotated with both @ClientMarshaller and @ServerMarshaller indicating that this class should be used for both marshalling on the client and on the server.

The demarshall() method does what its name implies: it is responsible for demarshalling the object from JSON and turning it back into a Java object.

The marshall() method does the opposite, and encodes the object into JSON for transmission on the wire.