緣由分析
緣由與RedisTemplate源碼中的默認序列化方式有關java
defaultSerializer = new JdkSerializationRedisSerializer( classLoader != null ? classLoader : this.getClass().getClassLoader());`
默認序列化使用的是JdkSerializationRedisSerializer,咱們進去看看redis
public JdkSerializationRedisSerializer(ClassLoader classLoader) { this(new SerializingConverter(), new DeserializingConverter(classLoader)); }
能夠看到這裏使用了SerializingConverter對象,再進去看看,
這裏的convert方法就是這個對象傳入JdkSerializationRedisSerializer後會被調用的方法this
public byte[] convert(Object source) { ByteArrayOutputStream byteStream = new ByteArrayOutputStream(1024); try { this.serializer.serialize(source, byteStream); return byteStream.toByteArray(); } catch (Throwable var4) { throw new SerializationFailedException("Failed to serialize object using " + this.serializer.getClass().getSimpleName(), var4); } }
能夠看出來這裏使用普通的serializer的serialize方法,並無什麼特別的
可是問題就在於,這裏的source是Object對象,
JdkSerializationRedisSerializer把傳入的值當Object對象進行序列化,因此能夠猜想這裏key出現的\xac\xed\x00\x05t\x00\tb其實多是對象頭信息。
spa
解決方案
咱們能夠使用下面這種方法設置其餘序列化方式,這樣就不會出現問題:code
redisTemplate.setKeySerializer(new StringRedisSerializer()); redisTemplate.setValueSerializer(new StringRedisSerializer()); redisTemplate.setHashKeySerializer(new StringRedisSerializer()); redisTemplate.setHashValueSerializer(new StringRedisSerializer());
可是這種方法明顯很不優雅,因此咱們應該直接使用StringRedisTemplate類來解決問題:對象
@Autowired private StringRedisTemplate stringRedisTemplate;
它幫咱們進行了設置序列化方式的封裝,咱們能夠看看它的構造方法:get
public StringRedisTemplate() { RedisSerializer<String> stringSerializer = new StringRedisSerializer(); setKeySerializer(stringSerializer); setValueSerializer(stringSerializer); setHashKeySerializer(stringSerializer); setHashValueSerializer(stringSerializer); }
固然也能夠使用配置的方式設置序列化方法,不過這裏就不做出說明了。源碼