IonObjectWriter
Jakob Jenkov |
The IonObjectWriter
(com.jenkov.iap.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 IAP 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 int
s).
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
From version 0.7.0 of IAP Tools for Java the IonObjectWriter
has received an extra 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);
Tweet | |
Jakob Jenkov |