出现这种乱码前缀的原因是没有进行序列化,因此导致在传输过程出现乱码问题,存到数据库,发现 key,hash key/value 都有 \xAC\xED\x00\x05t\x00 前缀。RedisTemplate类中默认是没有设置序列化的。

设置RedisTemplate的序列化方式
- import com.fasterxml.jackson.annotation.JsonAutoDetect;
- import com.fasterxml.jackson.annotation.PropertyAccessor;
- import com.fasterxml.jackson.databind.ObjectMapper;
- import org.springframework.context.annotation.Bean;
- import org.springframework.data.redis.connection.RedisConnectionFactory;
- import org.springframework.data.redis.core.RedisTemplate;
- import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
- import org.springframework.data.redis.serializer.StringRedisSerializer;
-
- public class RedisConfig {
- @Bean(name = "redisTemplate")
- //配置redisTemplate
- //默认情况下redisTemplate只能支持redisTemplate<String,String>
- //需要自定义 RedisTemplate,设置序列化
- public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory factory){
- RedisTemplate<String,Object> template = new RedisTemplate <>();
- template.setConnectionFactory(factory);
-
- Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
- ObjectMapper om = new ObjectMapper();
- om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
- om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
- jackson2JsonRedisSerializer.setObjectMapper(om);
-
- StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
- // key采用String的序列化方式
- template.setKeySerializer(stringRedisSerializer);
- // hash的key也采用String的序列化方式
- template.setHashKeySerializer(stringRedisSerializer);
- // value序列化方式采用jackson
- template.setValueSerializer(jackson2JsonRedisSerializer);
- // hash的value序列化方式采用jackson
- template.setHashValueSerializer(jackson2JsonRedisSerializer);
- template.afterPropertiesSet();
- return template;
- }
- }
注意:用了StringRedisSerializer之后,redis库的数据都是以String类型保存,所以int类型的整数,在保存时,会类型上升, 先变成double,然后再存成String,也就是1会存成"1.0",所以如果保存int数据时,需要自己在代码中单独处理下。上面修改全局配置不能兼容新老数据,新增配置可以兼容。
修改序列化方式后,数据不兼容报错
org.springframework.data.redis.serializer.SerializationException: Cannot deserialize; nested exception is org.springframework.core.serializer.support.SerializationFailedException: Failed to deserialize payload. Is the byte array a result of corresponding serialization for DefaultDeserializer?; nested exception is java.io.StreamCorruptedException: invalid stream header: E5A487E6
- @Configuration
- public class RedisConfig {
-
- @Bean
- @Primary
- public RedisTemplate redisTemplate(RedisConnectionFactory connectionFactory) {
- RedisTemplate redisTemplate = new RedisTemplate<>();
- redisTemplate.setConnectionFactory(connectionFactory);
- redisTemplate.setKeySerializer(new StringRedisSerializer());
- redisTemplate.setValueSerializer(new StringRedisSerializer());
- redisTemplate.setHashKeySerializer(new StringRedisSerializer());
- redisTemplate.setHashValueSerializer(new StringRedisSerializer());
- return redisTemplate;
- }
-
- @Bean(name = "ByteRedisTemplate")
- public RedisTemplate ByteRedisTemplate(
- RedisConnectionFactory redisConnectionFactory) {
- RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
- redisTemplate.setConnectionFactory(redisConnectionFactory);
- redisTemplate.setKeySerializer(new StringRedisSerializer());
- redisTemplate.setValueSerializer(RedisSerializer.byteArray());
- redisTemplate.setHashKeySerializer(new StringRedisSerializer());
- redisTemplate.setHashValueSerializer(RedisSerializer.byteArray());
- return redisTemplate;
- }
- }
使用方法
- @RestController
- public class PublishDemo {
-
- @Autowired
- private RedisTemplate redisTemplate;
-
- @Autowired
- @Qualifier("ByteRedisTemplate")
- private RedisTemplate byteRedisTemplate;
-
- @RequestMapping("set")
- public void set() {
- String key1 = "t1";
- String value = "12345";
- String key2 = "t2";
- String value2 = "54321";
- redisTemplate.opsForValue().set(key1, value);
- byteRedisTemplate.opsForValue().set(key2, value2.getBytes());
- }
-
- @RequestMapping("get")
- public void get() {
- Object t1 = redisTemplate.opsForValue().get("t1");
- System.out.println("t1:" + t1.toString());
- Object o = byteRedisTemplate.opsForValue().get("t2");
- System.out.println("t2:" + Arrays.toString((byte[]) o));
- }
- }
entityMap.forEach((field, value) -> redisTemplate.opsForHash().put(String.format(REDIS_CONN_KEY, entity.getId()), field, value != null ? String.valueOf(value) : ""));
- if (!isset($this->redis) || !$this->redis->isConnected()) {
- $this->setRedis();
- }
- $this->redis->exists($key);
-
- /**
- * 连接redis.
- */
- private function setRedis()
- {
- if (isset($this->redis) && $this->redis->isConnected()) {
- $this->redis->disconnect();
- }
- $this->redis = new RedisClient($this->container->getParameter('redis_mq')); //重连redis;
- }