Wednesday, August 28, 2013

Json conversion: Convert one of the fields of the object as binary data

Json conversion: Convert one of the fields of the object as binary data

Problem statement: I had an object that I wanted to convert to JSON. However, one of the fields of this object was a serializable-blob and hence I wanted to save it in binary/byte-array format instead of String format.

Solution:
1.     Write a custom JsonSerializer and JsonDeserializer as shown below
2.     Annotate the getter/setter of the blob-field with this custom serializer/deserializer respectively.

Object:
public class TestObject {
      private String name = null;
      private MyBlob data = null;
      public TestObject() {
            super();
      }
      @JsonSerialize(using=ByteArraySerializer.class)
      public MyBlob getData() {
            return data;
      }
      @JsonDeserialize(as=MyBlob.class, using=ByteArrayDeserializer.class)
      public void setData(MyBlob data) {
            this.data = data;
      }
      public String getName() {
            return name;
      }
      public void setName(String name) {
            this.name = name;
      }
}

JsonSerializer:
//(You can find out some other object-serializer (or write your own) to avoid dependency over Cassandra-code)
import me.prettyprint.cassandra.serializers.ObjectSerializer;
import org.codehaus.jackson.JsonGenerator;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.map.JsonSerializer;
import org.codehaus.jackson.map.SerializerProvider;

public class ByteArraySerializer extends JsonSerializer<Object> {
                @Override
                public void serialize(Object value, JsonGenerator jgen,
                                                SerializerProvider provider) throws IOException,
                                                JsonProcessingException {
                                byte[] bytes = ObjectSerializer.get().toBytes(value);
                                jgen.writeBinary(bytes);
                }
}

JsonDeserializer:
import java.io.IOException;
//(You can find out some other object-deserializer (or write your own) to avoid dependency over Cassandra-code)
import me.prettyprint.cassandra.serializers.ObjectSerializer;
import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.map.DeserializationContext;
import org.codehaus.jackson.map.JsonDeserializer;

public class ByteArrayDeserializer extends JsonDeserializer<Object> {
                @Override
                public Object deserialize(JsonParser jp, DeserializationContext ctxt)
                                                throws IOException, JsonProcessingException {
                                byte[] bytes = jp.getBinaryValue();
                                Object obj = ObjectSerializer.get().fromBytes(bytes);
                                return obj;
                }
}

-          Sarang Anajwala