diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/std/SqlBlobDeserializer.java b/src/main/java/com/fasterxml/jackson/databind/deser/std/SqlBlobDeserializer.java new file mode 100644 index 0000000000..3e539f1cbe --- /dev/null +++ b/src/main/java/com/fasterxml/jackson/databind/deser/std/SqlBlobDeserializer.java @@ -0,0 +1,54 @@ +package com.fasterxml.jackson.databind.deser.std; + +import java.io.IOException; +import java.sql.Blob; +import java.util.Arrays; +import java.util.UUID; + +import javax.sql.rowset.serial.SerialBlob; + +import com.fasterxml.jackson.core.Base64Variants; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.exc.InvalidFormatException; + + +/* + * Deserializer from base64 string to {@link java.sql.Blob} + */ + +public class SqlBlobDeserializer extends FromStringDeserializer +{ + private static final long serialVersionUID = 1L; + + + public SqlBlobDeserializer() { super(Blob.class); } + + @Override + public Object getEmptyValue(DeserializationContext ctxt) { + + return null; + } + + @Override + protected Blob _deserialize(String data, DeserializationContext ctxt) throws IOException + { + try { + return new SerialBlob(ctxt.getBase64Variant().decode(data)); + } + catch(Exception e) { + throw new JsonMappingException("Failed to Decode the Base64 String into Blob"); + } + + } + +// @Override +// protected Blob _deserializeEmbedded(Object ob, DeserializationContext ctxt) throws IOException +// { +// if (ob instanceof byte[]) { +// return _fromBytes((byte[]) ob, ctxt); +// } +// return super._deserializeEmbedded(ob, ctxt); +// } + + } \ No newline at end of file diff --git a/src/main/java/com/fasterxml/jackson/databind/ext/OptionalHandlerFactory.java b/src/main/java/com/fasterxml/jackson/databind/ext/OptionalHandlerFactory.java index eff9d5d8b7..5edeea8a18 100644 --- a/src/main/java/com/fasterxml/jackson/databind/ext/OptionalHandlerFactory.java +++ b/src/main/java/com/fasterxml/jackson/databind/ext/OptionalHandlerFactory.java @@ -3,12 +3,16 @@ import java.util.HashMap; import java.util.Map; -import com.fasterxml.jackson.databind.*; +import com.fasterxml.jackson.databind.BeanDescription; +import com.fasterxml.jackson.databind.DeserializationConfig; +import com.fasterxml.jackson.databind.JavaType; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializationConfig; import com.fasterxml.jackson.databind.deser.Deserializers; import com.fasterxml.jackson.databind.ser.Serializers; import com.fasterxml.jackson.databind.ser.std.DateSerializer; -import com.fasterxml.jackson.databind.ser.std.SqlDateSerializer; -import com.fasterxml.jackson.databind.ser.std.SqlTimeSerializer; import com.fasterxml.jackson.databind.util.ClassUtil; /** @@ -88,6 +92,9 @@ public class OptionalHandlerFactory implements java.io.Serializable private final static String CLS_NAME_JAVA_SQL_TIMESTAMP = "java.sql.Timestamp"; private final static String CLS_NAME_JAVA_SQL_DATE = "java.sql.Date"; private final static String CLS_NAME_JAVA_SQL_TIME = "java.sql.Time"; + private final static String CLS_NAME_JAVA_SQL_BLOB = "java.sql.Blob"; + private final static String CLS_NAME_JAVA_SQL_SERIALBLOB = "javax.sql.rowset.serial.SerialBlob"; + protected OptionalHandlerFactory() { _sqlDeserializers = new HashMap<>(); @@ -95,6 +102,8 @@ protected OptionalHandlerFactory() { "com.fasterxml.jackson.databind.deser.std.DateDeserializers$SqlDateDeserializer"); _sqlDeserializers.put(CLS_NAME_JAVA_SQL_TIMESTAMP, "com.fasterxml.jackson.databind.deser.std.DateDeserializers$TimestampDeserializer"); + _sqlDeserializers.put(CLS_NAME_JAVA_SQL_BLOB, + "com.fasterxml.jackson.databind.deser.std.SqlBlobDeserializer"); _sqlSerializers = new HashMap<>(); // 09-Jan-2015, tatu: As per [databind#1073], let's try to guard against possibility @@ -104,6 +113,8 @@ protected OptionalHandlerFactory() { _sqlSerializers.put(CLS_NAME_JAVA_SQL_TIMESTAMP, DateSerializer.instance); _sqlSerializers.put(CLS_NAME_JAVA_SQL_DATE, "com.fasterxml.jackson.databind.ser.std.SqlDateSerializer"); _sqlSerializers.put(CLS_NAME_JAVA_SQL_TIME, "com.fasterxml.jackson.databind.ser.std.SqlTimeSerializer"); + _sqlSerializers.put(CLS_NAME_JAVA_SQL_BLOB, "com.fasterxml.jackson.databind.ser.std.SqlBlobSerializer"); + _sqlSerializers.put(CLS_NAME_JAVA_SQL_SERIALBLOB, "com.fasterxml.jackson.databind.ser.std.SqlBlobSerializer"); } /* diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/std/SqlBlobSerializer.java b/src/main/java/com/fasterxml/jackson/databind/ser/std/SqlBlobSerializer.java new file mode 100644 index 0000000000..ecefa76349 --- /dev/null +++ b/src/main/java/com/fasterxml/jackson/databind/ser/std/SqlBlobSerializer.java @@ -0,0 +1,62 @@ +package com.fasterxml.jackson.databind.ser.std; + +import java.io.IOException; +import java.sql.Blob; +import java.util.Base64; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.annotation.JacksonStdImpl; + +/** + * This is serializer for {@link java.sql.Blob} into base64 String + */ + +@JacksonStdImpl +@SuppressWarnings("serial") +public class SqlBlobSerializer +extends StdScalarSerializer +{ + + public SqlBlobSerializer() { + super(Blob.class); + } + + + + @Override + public void serialize(Blob value, JsonGenerator gen, + SerializerProvider serializers) throws IOException { + // TODO Auto-generated method stub + + try { + int bLength = (int) value.length(); + byte[] blob1 = value.getBytes(1, bLength); + gen.writeBinary(blob1); +// gen.writeString(Base64.getEncoder().encodeToString(blob1)); + + + } + catch(Exception e) { + + throw new JsonMappingException("Failed to serialize Blob into Base64 String"); + } + + + } + + @Override + public boolean isEmpty(SerializerProvider provider, Blob value) { + return value==null; + } + + // @Override + // public Class handledType() { + // + // return Blob.class; + // } + + +} diff --git a/src/test/java/com/fasterxml/jackson/databind/ext/SqlBlobDeserializationTest.java b/src/test/java/com/fasterxml/jackson/databind/ext/SqlBlobDeserializationTest.java new file mode 100644 index 0000000000..039646885f --- /dev/null +++ b/src/test/java/com/fasterxml/jackson/databind/ext/SqlBlobDeserializationTest.java @@ -0,0 +1,66 @@ +package com.fasterxml.jackson.databind.ext; + +import java.sql.Blob; + +import javax.sql.rowset.serial.SerialBlob; + +import com.fasterxml.jackson.core.Base64Variants; +import com.fasterxml.jackson.databind.BaseMapTest; +import com.fasterxml.jackson.databind.ObjectMapper; + +// Tests for `java.sql.Date`, `java.sql.Time` and `java.sql.Timestamp` +public class SqlBlobDeserializationTest extends BaseMapTest +{ + static class BlobObject { + Blob sqlBlob1; + + public Blob getSqlBlob1() { + return sqlBlob1; + } + + public void setSqlBlob1(Blob sqlBlob1) { + this.sqlBlob1 = sqlBlob1; + } + + + } + + /* + /********************************************************** + /* Test methods + /********************************************************** + */ + + private final ObjectMapper m = new ObjectMapper(); + public void testSqlBlobDeserializer() throws Exception { + + String testWord="TestObject1"; + String base64Blob=Base64Variants.getDefaultVariant().encode(testWord.getBytes()); + + String json=m.writeValueAsString(base64Blob); + Blob obj2=m.readValue(json, Blob.class); + String result=new String( + obj2.getBytes(1L, (int)obj2.length())); + assertEquals(result, testWord); + + + } + public void testSqlBlobDeserializer2() throws Exception { + + String testWord="TestObject1"; + SerialBlob blob1=new SerialBlob(testWord.getBytes()); + + BlobObject obj1=new BlobObject(); + obj1.sqlBlob1=blob1; + + String json=m.writeValueAsString(obj1); + BlobObject obj2=m.readValue(json, BlobObject.class); + String result=new String( + obj2.getSqlBlob1().getBytes(1L, (int)obj2.getSqlBlob1().length())); + assertEquals(result, testWord); + + + } + + +} diff --git a/src/test/java/com/fasterxml/jackson/databind/ext/SqlBlobSerializationTest.java b/src/test/java/com/fasterxml/jackson/databind/ext/SqlBlobSerializationTest.java new file mode 100644 index 0000000000..ef80f0b5e4 --- /dev/null +++ b/src/test/java/com/fasterxml/jackson/databind/ext/SqlBlobSerializationTest.java @@ -0,0 +1,51 @@ +package com.fasterxml.jackson.databind.ext; + +import java.sql.Blob; +import java.util.Base64; + +import javax.sql.rowset.serial.SerialBlob; + +import com.fasterxml.jackson.core.Base64Variant; +import com.fasterxml.jackson.core.Base64Variants; +import com.fasterxml.jackson.databind.BaseMapTest; +import com.fasterxml.jackson.databind.ObjectMapper; + +// Tests for `java.sql.Date`, `java.sql.Time` and `java.sql.Timestamp` +public class SqlBlobSerializationTest extends BaseMapTest +{ + static class BlobObject { + // @JsonSerialize(using=SqlBlobSerializer.class) + Blob sqlBlob1; + + public Blob getSqlBlob1() { + return sqlBlob1; + } + + public void setSqlBlob1(Blob sqlBlob1) { + this.sqlBlob1 = sqlBlob1; + } + + + } + + /* + /********************************************************** + /* Test methods + /********************************************************** + */ + public void testSqlBlobSerializer() throws Exception { + ObjectMapper m = new ObjectMapper(); + String testWord="TestObject1"; + SerialBlob blob1=new SerialBlob(testWord.getBytes()); + String base64Blob=Base64Variants.getDefaultVariant().encode(testWord.getBytes()); + + + BlobObject obj1=new BlobObject(); + obj1.sqlBlob1=blob1; + + String json=m.writeValueAsString(obj1); + assertEquals("{\"sqlBlob1\":\""+base64Blob+"\"}", json); + + + } +}