Tech and Media Labs
This site uses cookies to improve the user experience.




IonObjectWriter

Jakob Jenkov
Last update: 2017-02-16

The IonObjectWriter (com.nanosai.gridops.ion.write.IonObjectWriter) can write Java objects to ION with a single method call. The IonObjectWriter uses Java Reflection to inspect the object's class and generate the corresponding ION fields. This tutorial explains how to use the IonObjectWriter.

Writing Java objects using the IonObjectWriter is slower than writing objects using the IonWriter directly, but it is much easier to do. You can see the performance difference in our ION Performance Benchmarks.

Creating an IonObjectWriter

Creating an IonObjectWriter is done like this:

IonObjectWriter writer = new IonObjectWriter(MyClass.class);

Notice how the IonObjectWriter constructor takes a Java class object as parameter. The created IonObjectWriter instance can only write objects of that class. Thus, if you need to write objects of different classes to ION, you need to create an IonObjectWriter for each class you want to write objects of.

What goes on inside the IonObjectWriter constructor is pretty expensive, so you should reuse IonObjectWriter instances as much as possible.

The IonObjectWriter is not thread safe, so you should not share IonObjectWriter instances across threads. Only within the same thread.

Writing Objects

Writing objects is done using the writeObject() method. Here is an example of writing an object using the IonObjectWriter writeObject() method:

byte[] dest       = new byte[1024];
int    destOffset = 0;

IonObjectWriter writer = new IonObjectWriter(MyClass.class);
MyClass pojo = new MyClass();

int maxLengthLength = 2;
int bytesWritten = writer.writeObject(pojo, maxLengthLength, dest, destOffset);

The example first creates a byte array into which the serialized ION data is written, and defines the offset into this byte array from which the ION data is to be written.

Second an IonObjectWriter is created, and a POJO instance is created too.

Third, a maxLengthLength variable is defined with the value 2. This variable defines the maximum number of bytes necessary to represent the length of the whole serialized ION data. The value 2 means that we know the total serialized size of the ION data will not exceed 65,535 bytes. The number 65,535 is the highest number that can be represented by 2 bytes. The IonObjectWriter uses this value internally to determine how many length bytes to reserve for the ION Object field (and for any other nested complex ION field).

Note, that while ION allows up to 15 length bytes, the Java API here only allows up to 4 length bytes, since that is the limit of a Java byte array (array indexes are 4 byte ints).

Finally, the POJO is serialized to the byte array with the writeObject() method. The writeObject() takes the POJO to serialize, the maximum length length required to represent the length of the serialized data, the destination byte array and an offset into that array as parameters. The writeObject() method returns the total number of bytes written to the destination byte array.

The IonObjectWriter Uses the Fields of a Class

The IonObjectWriter uses Java reflection to see what fields the target class has. It is these fields that are written. The IonObjectWriter will write all fields of a class, regardless of whether they are private, transient etc. The IonObjectWriter can, and will, access them all. The fields are access directly. Getter methods are ignored.

When writing the fields of an object the IonObjectWriter uses the field name (variable name) as the ION Key value for that field. ION Key fields is how ION encodes property names of objects.

If you want to exclude fields from serialization, or use different ION Key names for them in the serialized ION data, you can use an IIonObjectWriterConfigurator instance. See next section for details.

Configuring the IonObjectWriter

The IonObjectWriter has a constructor which can take an extra IIonObjectWriterConfigurator instance as parameter. This IIonObjectWriterConfigurator can configure the IonObjectWriter.

Here is how calling the IonObjectWriter constructor with an anonymous implementation of the IIonObjectWriterConfigurator interface looks:

IIonObjectWriterConfigurator configurator = new IIonObjectWriterConfigurator() {
    @Override
    public void configure(IonFieldWriterConfiguration config) {

    }
};

IonObjectWriter writer = new IonObjectWriter(MyClass.class, configurator);

The IIonObjectWriterConfigurator interface only contains a single method named configure(). This method is called by the IonObjectWriter constructor one time per field in the target class.

Inside the configure() method you can set the configuration for the given field. The IonFieldWriterConfiguration object contains the configuration of a single field. The IonFieldWriterConfiguration object contains the following fields:

Field   field
String  fieldName
String  alias
boolean include

The field and fieldName properties are already filled in. The field property contains the java.lang.reflect.Field instance representing the field you can configure. The fieldName contains the name of the field which is the same value as you can obtain from calling field.getName() .

The alias property is null when configure() is called. If you set a new String value for alias, the IonObjectWriter will use that alias in the serialized ION data instead of the original field name. This is useful if the reader of the ION data expects a different field name, or to just shorten the field names in the serialized ION data.

The include property is true when configure() is called, meaning that the given field will be included in ION data written by this IonObjectWriter instance. If you set include to false then the corresponding field will be exluded from ION data written by this IonObjectWriter .

Here is an example that sets a new alias for one property and exclude another:

IIonObjectWriterConfigurator configurator = new IIonObjectWriterConfigurator() {
    @Override
    public void configure(IonFieldWriterConfiguration config) {
        if("firstName".equals(config.fieldName)) {
            config.alias = "name";
        }
        if("lastName".equals(config.fieldName)) {
            config.include = false;
        }

    }
};

IonObjectWriter writer = new IonObjectWriter(MyClass.class, configurator);

Jakob Jenkov




Copyright  Jenkov Aps
Close TOC