Complex Data Types
The parameters and return types of the server commands and client callbacks may be:
  • primitive types;
  • complex types;
  • arrays of primitive types or complex types.

Complex data types are defined using Java interfaces. This is because allowing a class as parameter or return type would require the implementation of the class to exist both on the client and server side. The purpose of complex types is to transmit structured data rather than implementations and this is accomplished through interfaces. In our sample we are using an IMessagePacket datatype that represent a message part. The reason for this type is that we need to return a last packet flag with the data.

The next section will present a more complex example including a command that takes a postal address as argument and returns the list of persons living at this address.

Define the Types Interfaces
Define the interfaces corresponding to the complex data types, and the server command:
public interface IPostalAddress
{
    String getStreetNumber();
    String getStreetName();
    String getSuite();
    String getCity();
    String getStateOrProvince();
    String getCountry()
    String getZipOrPC();
}

public interface IPersonData
{
    String getFirstName();
    String getLastName();
    String getSocialInsuranceNumber();
}

public interface IResidence
{
    IPersonData[] getPersonsAtAddress( IPostalAddress adress );
}
These interfaces must be deployed to both the server and the client into the interfaces jar file.

For the complex type interfaces only the data returned by the getter methods of complex parameters or returned objects will be serialized/deserialized, not all the internal fields of the implementations. If a getter method returns a complex data type the serialization/deserialization will occur recursively. The children of the hierarchy may not reference parent nodes.

Implement the Complex Types
After establishing the interfaces implement a client class that implements the IPostalAddress interface:
public PostalAddress implements IPostalAddress
{
    private String streetNumber;
    // declare a private member for each address component
    // ...

    public void setStreetNumber( String streetNumber )
    {
        this.streetNumber = streetNumber;
    }

    public String getStreetNumber()
    {
        return streetNumber;
    }

    // implement setter and getter methods for all address components
    // ...
}
Implement a server class that implements the return type interface IPersonData:
public PersonData implements IPersonData
{
    ...
}

Implement the Command
Finally implement and deploy the server command that implements the IResidence interface:
public class Residence implements IResidence
{
    public IPersonData[] getPersonsAtAddress( IPostalAddress adress )
    {
        ...
    }
}