Redis序列化、乱码问题

Redis序列化问题

每当初学者学习Redis,并且使用SpringBoot整合Redis的时候,总会看到别人使用这种东西—配置类,然后自己又看不懂,oh,fuck!!

这是为什么,为什么要有这个配置类???

package com.example.txf_redis.config;

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.context.annotation.Configuration;
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;

@Configuration
public class RedisConfig {
    @Bean
    //配置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;
    }
}

下面我来发表一下我自己的看法:

1.不用配置类

在这里插入图片描述

下面是实体类

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student implements Serializable {
    private static final long serialVersionUID = -1;
    private Integer id;
    private String name;
    private String desc;
}

@Data
public class People implements Serializable {
    private static final long serialVersionUID = -1;
    private Student student;

    public People() {
    }

    public People(Student student) {
        this.student = student;
    }

    private Integer getId() {
        return student.getId();
    }

    private String getName() {
        return student.getName();
    }

    private String getDesc() {
        return student.getDesc();
    }


}

People对象里面有一个成员叫Student

运行测试,第一个方法,然后去Redis里面查看key

在这里插入图片描述

就算我们不用JSON工具,直接插入,同样有问题

@Test
    void contextLoads() {
        Student student = new Student(1, "田小锋", "爱吃饭");
        People people = new People(student);
//        redisTemplate.opsForValue().set("user"+student.getId(), JSON.toJSONString(people));
        redisTemplate.opsForValue().set("user"+student.getId(),people);
    }

为什么Key是那样的呢?不应该只是user1吗?

这就回到了主题了,序列化问题。

因redis默认使用JdkSerializationRedisSerializer来进行序列化,造成key是乱码

原因分析:
spring-data-redis 的 RedisTemplate<K, V>模板类 在操作redis时默认使用JdkSerializationRedisSerializer 来进行序列化。spring操作redis是在jedis客户端基础上
进行的,而jedis客户端与redis交互的时候协议中定义是用byte类型交互,
看到spring-data-redis中RedisTemplate<K, V>在操作的时候k,v是泛型对象,
而不是byte[]类型的,
这样导致的一个问题就是,如果不对RedisTemplate进行设置,
spring会默认采用defaultSerializer = new JdkSerializationRedisSerializer();
这个方法来对key、value进行序列化操作,
JdkSerializationRedisSerializer它使用的编码是ISO-8859-1
    
来自:https://blog.csdn.net/m4330187/article/details/108091447

总的来看就是编码有问题

2.使用配置类

所以我们需要用一下这个配置类,在开头已经给出了,(不一定要这个一模一样的啊)我们把配置类,重新使用上,再试试

在这里插入图片描述

然后发现,存取都没有问题了!

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值