diff --git a/src/main/java/org/redisson/client/codec/JsonJacksonMapValueCodec.java b/src/main/java/org/redisson/client/codec/JsonJacksonMapValueCodec.java new file mode 100644 index 000000000..33f06b086 --- /dev/null +++ b/src/main/java/org/redisson/client/codec/JsonJacksonMapValueCodec.java @@ -0,0 +1,47 @@ +package org.redisson.client.codec; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufInputStream; +import org.redisson.client.handler.State; +import org.redisson.client.protocol.Decoder; +import org.redisson.client.protocol.Encoder; +import org.redisson.codec.JsonJacksonCodec; + +import java.io.IOException; + +public class JsonJacksonMapValueCodec extends JsonJacksonCodec { + private final ObjectMapper mapper; + private TypeReference typeReference; + + public JsonJacksonMapValueCodec(Class klass) { + this(new TypeReference() { + }); + } + + public JsonJacksonMapValueCodec(TypeReference typeReference) { + this.typeReference = typeReference; + this.mapper = initObjectMapper(); + } + + @Override + public Decoder getMapValueDecoder() { + return new Decoder() { + @Override + public Object decode(ByteBuf buf, State state) throws IOException { + return mapper.readValue(new ByteBufInputStream(buf), typeReference); + } + }; + } + + @Override + public Encoder getMapValueEncoder() { + return new Encoder() { + @Override + public byte[] encode(Object in) throws IOException { + return mapper.writeValueAsBytes(in); + } + }; + } +} \ No newline at end of file diff --git a/src/main/java/org/redisson/codec/JsonJacksonCodec.java b/src/main/java/org/redisson/codec/JsonJacksonCodec.java index 342ad33fe..1cfe91c33 100755 --- a/src/main/java/org/redisson/codec/JsonJacksonCodec.java +++ b/src/main/java/org/redisson/codec/JsonJacksonCodec.java @@ -15,21 +15,10 @@ */ package org.redisson.codec; -import java.io.IOException; - -import org.redisson.client.codec.Codec; -import org.redisson.client.handler.State; -import org.redisson.client.protocol.Decoder; -import org.redisson.client.protocol.Encoder; - import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility; import com.fasterxml.jackson.annotation.JsonIdentityInfo; -import com.fasterxml.jackson.annotation.JsonIdentityReference; -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.ObjectIdGenerators; import com.fasterxml.jackson.databind.DeserializationFeature; @@ -39,11 +28,15 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper.DefaultTypeResolverBuilder; import com.fasterxml.jackson.databind.ObjectMapper.DefaultTyping; import com.fasterxml.jackson.databind.SerializationFeature; -import com.fasterxml.jackson.databind.annotation.JsonTypeIdResolver; import com.fasterxml.jackson.databind.jsontype.TypeResolverBuilder; - import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufInputStream; +import org.redisson.client.codec.Codec; +import org.redisson.client.handler.State; +import org.redisson.client.protocol.Decoder; +import org.redisson.client.protocol.Encoder; + +import java.io.IOException; /** * @@ -141,22 +134,22 @@ public class JsonJacksonCodec implements Codec { @Override public Decoder getMapKeyDecoder() { - return getMapValueDecoder(); + return decoder; } @Override public Encoder getMapKeyEncoder() { - return getMapValueEncoder(); + return encoder; } @Override public Decoder getValueDecoder() { - return getMapValueDecoder(); + return decoder; } @Override public Encoder getValueEncoder() { - return getMapValueEncoder(); + return encoder; } } diff --git a/src/test/java/org/redisson/RedissonCodecTest.java b/src/test/java/org/redisson/RedissonCodecTest.java index f713bdc7c..60c2c3429 100644 --- a/src/test/java/org/redisson/RedissonCodecTest.java +++ b/src/test/java/org/redisson/RedissonCodecTest.java @@ -1,14 +1,10 @@ package org.redisson; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; - +import com.fasterxml.jackson.core.type.TypeReference; import org.junit.Assert; import org.junit.Test; import org.redisson.client.codec.Codec; +import org.redisson.client.codec.JsonJacksonMapValueCodec; import org.redisson.codec.CborJacksonCodec; import org.redisson.codec.FstCodec; import org.redisson.codec.JsonJacksonCodec; @@ -19,6 +15,15 @@ import org.redisson.codec.SerializationCodec; import org.redisson.codec.SnappyCodec; import org.redisson.core.RMap; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static org.assertj.core.api.Assertions.assertThat; + public class RedissonCodecTest extends BaseTest { private Codec codec = new SerializationCodec(); private Codec kryoCodec = new KryoCodec(); @@ -28,6 +33,8 @@ public class RedissonCodecTest extends BaseTest { private Codec snappyCodec = new SnappyCodec(); private Codec msgPackCodec = new MsgPackJacksonCodec(); private Codec lz4Codec = new LZ4Codec(); + private Codec jsonListOfStringCodec = new JsonJacksonMapValueCodec>(new TypeReference>() { + }); @Test public void testLZ4() { @@ -83,6 +90,39 @@ public class RedissonCodecTest extends BaseTest { test(); } + @Test + public void testKryo() { + Config config = createConfig(); + config.setCodec(kryoCodec); + redisson = Redisson.create(config); + + test(); + } + + @Test + public void testCbor() { + Config config = createConfig(); + config.setCodec(cborCodec); + redisson = Redisson.create(config); + + test(); + + } + + @Test + public void testListOfStrings() { + Config config = createConfig(); + config.setCodec(new JsonJacksonCodec()); + redisson = Redisson.create(config); + + RMap> map = redisson.getMap("list of strings", jsonListOfStringCodec); + map.put("foo", new ArrayList(Arrays.asList("bar"))); + + RMap> map2 = redisson.getMap("list of strings", jsonListOfStringCodec); + + assertThat(map2).isEqualTo(map); + } + public void test() { RMap> map = redisson.getMap("getAll"); Map a = new HashMap(); @@ -111,23 +151,4 @@ public class RedissonCodecTest extends BaseTest { Assert.assertTrue(set.contains(new TestObject("1", "2"))); Assert.assertFalse(set.contains(new TestObject("1", "9"))); } - - @Test - public void testKryo() { - Config config = createConfig(); - config.setCodec(kryoCodec); - redisson = Redisson.create(config); - - test(); - } - - @Test - public void testCbor() { - Config config = createConfig(); - config.setCodec(cborCodec); - redisson = Redisson.create(config); - - test(); - - } } diff --git a/src/test/java/org/redisson/client/codec/JsonJacksonMapValueCodecTest.java b/src/test/java/org/redisson/client/codec/JsonJacksonMapValueCodecTest.java new file mode 100644 index 000000000..b0d4b4ebe --- /dev/null +++ b/src/test/java/org/redisson/client/codec/JsonJacksonMapValueCodecTest.java @@ -0,0 +1,63 @@ +package org.redisson.client.codec; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.PooledByteBufAllocator; +import org.junit.Before; +import org.junit.Test; +import org.redisson.client.handler.State; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.assertj.core.api.Assertions.assertThat; + +public class JsonJacksonMapValueCodecTest { + + private final JsonJacksonMapValueCodec>> mapCodec = new JsonJacksonMapValueCodec>>(new TypeReference>>() { + }); + + private final JsonJacksonMapValueCodec stringCodec = new JsonJacksonMapValueCodec(String.class); + + private HashMap> map; + + @Before + public void setUp() throws Exception { + map = new HashMap>(); + map.put("foo", new ArrayList(Arrays.asList("bar"))); + } + + @Test + public void shouldDeserializeTheMapCorrectly() throws Exception { + ByteBuf buf = new PooledByteBufAllocator(true).buffer(); + buf.writeBytes(new ObjectMapper().writeValueAsBytes(map)); + assertThat(mapCodec.getMapValueDecoder().decode(buf, new State(false))) + .isInstanceOf(Map.class) + .isEqualTo(map); + } + + @Test + public void shouldSerializeTheMapCorrectly() throws Exception { + assertThat(new String(mapCodec.getMapValueEncoder().encode(map), "UTF-8")) + .isEqualTo("{\"foo\":[\"bar\"]}"); + } + + @Test + public void shouldDeserializeTheStringCorrectly() throws Exception { + ByteBuf buf = new PooledByteBufAllocator(true).buffer(); + buf.writeBytes(new ObjectMapper().writeValueAsBytes("axk")); + assertThat(stringCodec.getMapValueDecoder().decode(buf, new State(false))) + .isInstanceOf(String.class) + .isEqualTo("axk"); + } + + @Test + public void shouldSerializeTheStringCorrectly() throws Exception { + assertThat(new String(stringCodec.getMapValueEncoder().encode("foo"), "UTF-8")) + .isEqualTo("\"foo\""); + } +} \ No newline at end of file