SpringBoot使用RedisTemplate操作Redis时,key值出现 \xac\xed\x00\x05t\x00\tb

原因分析

原因与RedisTemplate源码中的默认序列化方式有关

defaultSerializer = new JdkSerializationRedisSerializer(
					classLoader != null ? classLoader : this.getClass().getClassLoader());`

默认序列化使用的是JdkSerializationRedisSerializer,我们进去看看

	public JdkSerializationRedisSerializer(ClassLoader classLoader) {
		this(new SerializingConverter(), new DeserializingConverter(classLoader));
	}

可以看到这里使用了SerializingConverter对象,再进去看看,
这里的convert方法就是这个对象传入JdkSerializationRedisSerializer后会被调用的方法

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其实可能是对象头信息。


解决方案

我们可以使用下面这种方法设置其他序列化方式,这样就不会出现问题:

redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setHashValueSerializer(new StringRedisSerializer());

但是这种方法明显很不优雅,所以我们应该直接使用StringRedisTemplate类来解决问题:

@Autowired
private StringRedisTemplate stringRedisTemplate;

它帮我们进行了设置序列化方式的封装,我们可以看看它的构造方法:

public StringRedisTemplate() {
		RedisSerializer<String> stringSerializer = new StringRedisSerializer();
		setKeySerializer(stringSerializer);
		setValueSerializer(stringSerializer);
		setHashKeySerializer(stringSerializer);
		setHashValueSerializer(stringSerializer);
	}

当然也可以使用配置的方式设置序列化方法,不过这里就不作出说明了。

posted @ 2019-10-10 14:19  肥宅快乐码  阅读(665)  评论(0编辑  收藏  举报