1.通过set进redis中的数据,get不到
String cityKey ="city_"+id; ValueOperations<String,City> operations = this.redisTemplate.opsForValue(); // 判断缓存中是否存在 if (this.redisTemplate.hasKey(cityKey)){ City city = operations.get(cityKey); return city; } // 从 DB 中获取 City city = this.cityRepository.findById(id).get(); // 添加的缓存中,时间10 operations.set(cityKey,city,100, TimeUnit.SECONDS);
在redis-cli 中查看
192.168.6.3:6379> keys *
xacxedx00x05tx00x06city_2
发现key值出现 xacxedx00x05tx00x06city_2 key是乱码
原因:序列化是默认用的JdkSerializationRedisSerializer
在redis配置中添加
//设置key序列-String序列化 template.setKeySerializer(new StringRedisSerializer());
2.如果希望java对象以json的方式存储到redis中
通常会在redis配置中添加
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); // 设置value的序列化规则 //json序列化 template.setValueSerializer(jackson2JsonRedisSerializer);
但是进行redis缓存get时会报错:java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to com.redis.springbootredis.pojo.City
1 java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to com.redis.springbootredis.pojo.City 2 at com.redis.springbootredis.service.impl.CityServiceImpl.findCityById(CityServiceImpl.java:59) 3 at com.redis.springbootredis.SpringBootRedisApplicationTests.testFindCityById(SpringBootRedisApplicationTests.java:25) 4 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 5 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 6 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 7 at java.lang.reflect.Method.invoke(Method.java:498) 8 at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) 9 at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) 10 at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) 11 at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) 12 at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:74) 13 at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:84) 14 at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75) 15 at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86) 16 at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84) 17 at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) 18 at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251) 19 at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97) 20 at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) 21 at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) 22 at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) 23 at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) 24 at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) 25 at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) 26 at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70) 27 at org.junit.runners.ParentRunner.run(ParentRunner.java:363) 28 at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190) 29 at org.junit.runner.JUnitCore.run(JUnitCore.java:137) 30 at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68) 31 at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47) 32 at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242) 33 at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
原因:redis中取出的对象数据为json,java.util.LinkedHashMap无法转换成city对象,
解决方式:在redis配置中添加
//解决查询缓存转换异常的问题 ObjectMapper om = new ObjectMapper(); om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(om);
还有一种方式:就是每次获取到对象数据进行json转换(每一都要转换太麻烦不太建议)
String str = JSONObject.toJSONString(operations.get(cityKey)); City cityy = JSON.parseObject(str,City.class);
笔者的redis配置类

1 import com.fasterxml.jackson.annotation.JsonAutoDetect; 2 import com.fasterxml.jackson.annotation.PropertyAccessor; 3 import com.fasterxml.jackson.databind.ObjectMapper; 4 import org.springframework.context.annotation.Bean; 5 import org.springframework.context.annotation.Configuration; 6 import org.springframework.data.redis.connection.RedisConnectionFactory; 7 import org.springframework.data.redis.core.RedisTemplate; 8 import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; 9 import org.springframework.data.redis.serializer.StringRedisSerializer; 10 11 /** 12 * @Author: GWL 13 * @Description: redis配置 14 * redisTemplate 序列化使用的jdkSerializeable, 存储二进制字节码, 所以自定义序列化类 15 * 一般redis的序列化方式主要有:字符串序列化、json序列化、xml序列化、jdk序列化 16 * 默认为 JdkSerializationRedisSerializer 17 * @Date: Create in 14:43 2019/5/14 18 */ 19 @Configuration 20 public class RedisConfig { 21 22 @Bean 23 public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisCollectionFactory) { 24 RedisTemplate template = new RedisTemplate(); 25 template.setConnectionFactory(redisCollectionFactory); 26 27 Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); 28 29 //解决查询缓存转换异常的问题 30 ObjectMapper om = new ObjectMapper(); 31 om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); 32 om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); 33 jackson2JsonRedisSerializer.setObjectMapper(om); 34 35 // 设置value的序列化规则 36 //json序列化 37 template.setValueSerializer(jackson2JsonRedisSerializer); 38 //String序列化 39 // template.setValueSerializer(new StringRedisSerializer()); 40 //jdk序列化 41 // template.setValueSerializer(new JdkSerializationRedisSerializer()); 42 43 //设置key序列-String序列化 44 template.setKeySerializer(new StringRedisSerializer()); 45 46 template.setHashKeySerializer(new StringRedisSerializer()); 47 template.setHashValueSerializer(new StringRedisSerializer()); 48 template.afterPropertiesSet(); 49 50 return template; 51 } 52 53 }
再次redis中查看缓存对象:redis中中文乱码,但是存取没影响
192.168.6.3:6379> keys *
1) "city_2"
192.168.6.3:6379> get city_2
"["com.redis.springbootredis.pojo.City",{"id":2,"name":"xe5xa4xa9xe6xb4xa5","description":"xe6xacxa2xe8xbfx8exe4xbdxa0xe6x9dxa5xe6x8cxa4xe5x9cxb0xe9x93x81","createDate":["java.sql.Timestamp",1557737066000]}]"
换个姿势再来一次
如何在get时取到它的中文呢?只需要在redis-cli 后面加上 –raw
192.168.6.3:6379> QUIT [root@localhost src]# ./redis-cli -h 192.168.6.3 -p 6379 --raw 192.168.6.3:6379> keys * city_2 192.168.6.3:6379> get city_2 ["com.redis.springbootredis.pojo.City",{"id":2,"name":"天津","description":"欢迎你来挤地铁","createDate":["java.sql.Timestamp",1557737066000]}]
有兴趣的朋友可以查看本人的spring-boot-redis:GitHub项目