Java使用RedisTemplate操作Redis遇到的坑
目录
- 坑一
- 坑二、用StringRedisTemplate和RedisTemplate取值赋值问题
- 总结
坑一
方法:
直接使用注入的方式
@AutoWired private RedisTemplate redisTemplate;
异常现象:
key会出现乱码
127.0.0.1:6379> keys *
1) "\xac\xed\x00\x05t\x00\x04name"
原因:
spring-data-redis的RedisTemplate<K, V>模板类在操作redis时默认使用JdkSerializationRedisSerializer来进行序列化
解决:
自定义RestTemplate,使用GenericJackson2jsonRedisSerializer解决序列化问题,注入的@AutoWired private RedisTemplate redisTemplate;其实是自定义的RestTemplate,
注意事项:
@Bean注入的bean是方法名,所以要目方法名写成restTemplate,要么写自定义的(如restTemplateInit()),在注入的时候就要用@Resources(name="restTemplateInit")
package com.example.demo.config; import lombok.Data; import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; import org.springframework.stereotype.Component; @Data @Component @Configuration @Slf4j public class RedisConfig { @Bean public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) { RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>(); redisTemplate.setConnectionFactory(redisConnectionFactory); // // 使用Jackson2JsonRedisSerialize 替换默认序列化 // Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); // // ObjectMapper objectMapper = new ObjectMapper(); // objectMapper.setVisibility(PropertyAccessor.ALL, JsonAwww.devze.comutoDetect.Visibility.ANY); // objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); // // jackson2JsonRedisSerializer.setObjectMapper(objectMapper); GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer(); StringRedisSerializer stringRedisSerializer = new StringRedisSejavascriptrializer(); // 设置value的序列化规则和 key的序列化规则 redisTemplate.setKeySerializer(stringRedisSerializer); redisTemplate.setValueSerializer(genericJackson2JsonRedisSerializer); redisTemplate.setHashKeySerializer(stringRedisSerializer); redisTemplate.setHashValueSerializer(genericJackson2JsonRedisSerializer); redisTemplate.setDefaultSerializer(genericJackson2JsonRedisSerializer); redisTemplawww.devze.comte.setEnableDefaultSerializer(true); redisTemplate.afterPropertiesSet(); return redisTemplate; } }
坑二、用StringRedisTemplate和RedisTemplate取值赋值问题
redisTemplate.opsForValue().set("test1", "123"); redisTemplate.opsForValue().set("test2", ayUser);
//stringRedisTemplate.opsForValue().set("test3", "{\"name\":\"jack\"}"); //value设置成{\"name\":\"jack\"}这样的json也没用,需要带上序列化的类,像下面这样 stringRedisTemplate.o编程客栈psForValue().set("test3", "{\"@class\":\"com.example.demo.model.AyUser\",\"id\":null,\"name\":\"shenzhen\",\"password\":null}");
System.out.println((String) redisTemplate.opsForValue().get("test1"));//123 System.out.println(stringRedisTemplate.opsForValue().get("test1"));//"123" System.out.println((AyUser) redisTemplate.opsForValuandroide().get("test2"));//AyUser(id=null, name=shenzhen, password=null) System.out.println(redisTemplate.opsForValue().get("test3"));//AyUser(id=null, name=shenzhen, password=null) System.out.println(stringRedisTemplate.opsForValue().get("test3"));//{"@class":"com.example.demo.model.AyUser","id":null,"name":"shenzhen","password":null}
使用上面注入的自定义的RedisTemplate都是可以反序列化成功的,如下!
但是使用的stringRedisTemplate虽然set的是返祖json格式的且带序列化的,但是不能直接通过强转实现(AyUser),需要通过com.alibaba.fastjson.JSON去反序列化
AyUser ayUser_3_0 = JSON.parseobject(stringRedisTemplate.opsForValue().get("test3_0"), AyUser.class);
通过ayUser_3_0.getName()就可以取到。
AyUser ayUser_2 = (AyUser) redisTemplate.opsForValue().get("test2");//ayUser_2.getName() AyUser ayUser_3 = (AyUser) redisTemplate.opsForValue().get("test3");//ayUser_3.getName()
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程客栈(www.devze.com)。
精彩评论