• Spring-boot整合Redis,遇到的问题


    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 }
    RedisConfig

    再次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项目

  • 相关阅读:
    POJ 1320 Street Numbers(佩尔方程)
    hdu 3292 No more tricks, Mr Nanguo
    佩尔方程
    hdu 4825 xor sum(字典树+位运算)
    Xor Sum 2(位运算)
    数串
    EJS
    JQuery性能优化
    常用正则
    JavaScript prototype继承中的问题
  • 原文地址:https://www.cnblogs.com/brokencolor/p/10867650.html
Copyright © 2020-2023  润新知