Search This Blog

Friday, April 25, 2014

Eneter JSON Serializer for Java

Implementation of JSON serializer that can be used with Eneter Messaging Framework for Java.
Eneter Messaging Framework uses the serialization to encode data structures into messages and the deserialization to decode messages back to data structures when they are received.

Eneter for Java and JSON

Although the framework provides several built-in serializers the JSON serializer is not part of Eneter Messaging Framework for Java. The reason is JSON serialization is not part of Java platform and so Eneter would have to provide either its own implementation or would have to integrate with an existing implementation.
The first alternative would mean to reinvent the wheel and the second one would create a dependency on a third party library which would violate one of Eneter principles to stay lightweight and easy to use.
Therefore the solution is to provide the JSON serializer by reusing an existing implementation but outside the Eneter library.

The article shows implementation of Eneter JSON serializer for Java based on GSON (Google's JSON serializer).

To experiment with the example bellow you need to:


Eneter Serializer

The serialization in Eneter is based on ISerializer interface which consists of two simple methods: serialize(...) and deserialize(...).

public interface ISerializer
{
    /**
     * Serializes data.
     * 
     * @param dataToSerialize Data to be serialized.
     * @param clazz represents the serialized type.
     * @return Object representing the serialized data.
     *         Based on the serializer implementation it can be byte[] or String.
     * @throws Exception If the serialization fails.
     */
    <T> Object serialize(T dataToSerialize, Class<T> clazz) throws Exception;
    
    /**
     * Deserializes data.
     * 
     * @param serializedData Data to be deserialized.
     * @return Deserialized object.
     * @throws Exception If the deserialization fails.
     */
    <T> T deserialize(Object serializedData, Class<T> clazz) throws Exception;
}

The interface is used across the whole framework and by providing a reference of this interface you can control which serializer will be used to encode and decode messages.

GSON in Eneter

Therefore, in order to integrate GSON (Google's implementation of JSON serializer) with Eneter we need to provide an implementation of ISerializer which would internally use GSON.

The whole implementation of such wrapper is very easy:

public class JsonSerializer implements ISerializer
{
    /**
     * Serialize to JSON.
     */
    @Override
    public <T> T deserialize(Object serializedData, Class<T> clazz)
            throws Exception
    {
        // Check input parameters.
        if (serializedData == null)
        {
            throw new IllegalArgumentException("Input parameter serializedData is null.");
        }
        if (serializedData instanceof String == false)
        {
            throw new IllegalArgumentException("Input parameter serializedData is not String.");
        }
        
        // Serialize using GSON.
        T aDeserializedObject = myGson.fromJson((String)serializedData, clazz);
        return aDeserializedObject;
    }

    /**
     * Deserialize from JSON.
     */
    @Override
    public <T> Object serialize(T dataToSerialize, Class<T> clazz)
            throws Exception
    {
        // Deserialize using GSON.
        String aSerializedObject = myGson.toJson(dataToSerialize);
        return aSerializedObject;
    }

    private Gson myGson = new Gson();
}

Example of Using

If not specified Eneter uses XmlSerializer by default. Therefore to enable JSON serialization you need to provide the serializer reference when constructing the communication components.

The following example shows how to use our JsonSerializer for sending messages:

// Provide JSON serializer when constructing the factory.
ISerializer aSerializer = new JsonSerializer();
IDuplexTypedMessagesFactory aFactory = new DuplexTypedMessagesFactory(aSerializer);

// Factory create duplex typed message sender that uses our JSON serializer.
myCreateUser = aFactory.createDuplexTypedMessageSender(String.class, UserData.class);

// Continue with subscribing and attaching the channel.
...

And of course do not forget to set JSON serializer in the service too:

// Provide JSON serializer when constructing the factory.
ISerializer aSerializer = new DataContractJsonStringSerializer();
IDuplexTypedMessagesFactory aFactory = new DuplexTypedMessagesFactory(aSerializer);

// Factory create duplex typed message sender that uses our JSON serializer.
myCreateUser = aFactory.createDuplexTypedMessageReceiver<string, UserData>();

// Continue with subscribing and attaching the channel.
...

No comments:

Post a Comment