文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

SpringBoot怎么结合Redis实现序列化

2023-07-02 06:26

关注

这篇文章主要介绍了SpringBoot怎么结合Redis实现序列化的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇SpringBoot怎么结合Redis实现序列化文章都会有所收获,下面我们一起来看看吧。

配置类

配置 Jackson2JsonRedisSerializer 序列化策略

下面就开始自动配置类的书写

我使用的是 Jackson2JsonRedisSerializer 来对对象进行序列化,所以首先需要一个方法,来配置 Jackson2JsonRedisSerializer 序列化策略

private Jackson2JsonRedisSerializer<Object> serializer() {        // 使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);        ObjectMapper objectMapper = new ObjectMapper();        // 指定要序列化的域,field,get和set,以及修饰符范围,ANY是都有包括private和public        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);        // 指定序列化输入的类型,类必须是非final修饰的,final修饰的类,比如String,Integer等会跑出异常        objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);        jackson2JsonRedisSerializer.setObjectMapper(objectMapper);        return jackson2JsonRedisSerializer;    }

这里要注意的是

objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);

这一句,这一句非常的重要,作用是序列化时将对象全类名一起保存下来

设置之后的序列化结果如下:

[
    "com.buguagaoshu.redis.model.User",
    {
        "name": "1",
        "age": "11",
        "message": "牛逼"
    }
]

不设置的话,序列化结果如下,将无法反序列化

{
        "name": "1",
        "age": "11",
        "message": "牛逼"
    }

一开始,我在网上搜了一下,发现大多数教程因为时间的原因,这一句用的是

objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);

但当我把这段代码写入的时候,发现Idea提示我

SpringBoot怎么结合Redis实现序列化

着是一个过时的方法,由于我当时并不知道这句话的意思,就把这段代码注释了,觉得可能没什么用,但注释后在向Redis里写数据的时候,数据会变成

SpringBoot怎么结合Redis实现序列化

SpringBoot怎么结合Redis实现序列化

导致数据无法反序列化。

最后我查看了这个方法的源码,找到了

SpringBoot怎么结合Redis实现序列化

SpringBoot怎么结合Redis实现序列化

通过注释,我得到了这段代码的最新写法。

也明白了这段代码的作用。

配置  RedisTemplate

@Bean    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();        redisTemplate.setConnectionFactory(redisConnectionFactory);        // 用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值        redisTemplate.setValueSerializer(serializer());        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();        // 使用StringRedisSerializer来序列化和反序列化redis的key值        redisTemplate.setKeySerializer(stringRedisSerializer);        // hash的key也采用String的序列化方式        redisTemplate.setHashKeySerializer(stringRedisSerializer);        // hash的value序列化方式采用jackson        redisTemplate.setHashValueSerializer(serializer());        redisTemplate.afterPropertiesSet();        return redisTemplate;    }

这里就没有什么需要注意的了,按照自己的需求,来配置序列化的方式

配置缓存策略

@Bean    public CacheManager cacheManager(RedisConnectionFactory factory) {        RedisSerializer<String> redisSerializer = new StringRedisSerializer();        // 配置序列化(解决乱码的问题)        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()                // 缓存有效期                .entryTtl(timeToLive)                // 使用StringRedisSerializer来序列化和反序列化redis的key值                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))                // 使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(serializer()))                // 禁用空值                .disableCachingNullValues();        return RedisCacheManager.builder(factory)                .cacheDefaults(config)                .build();    }

测试代码

@SpringBootTestpublic class RedisApplicationTests {    @Autowired    private RedisTemplate<String, Object> redisTemplate;    @Test    void contextLoads() throws Exception {        User user = new User();        user.setName("15");        user.setAge(20);        user.setMessage("牛逼");        redisTemplate.opsForValue().set(user.getName(), user);        User getUser = (User) redisTemplate.opsForValue().get(user.getName());        System.out.println(getUser);        System.out.println(getUser.getMessage());    }}

再来查看Redis中的数据

SpringBoot怎么结合Redis实现序列化

数据正常,并且系统也能正常的反序列化了。

完整代码

package com.buguagaoshu.redis.config;import com.fasterxml.jackson.annotation.JsonAutoDetect;import com.fasterxml.jackson.annotation.PropertyAccessor;import com.fasterxml.jackson.databind.ObjectMapper;import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;import org.springframework.beans.factory.annotation.Value;import org.springframework.cache.CacheManager;import org.springframework.cache.annotation.CachingConfigurerSupport;import org.springframework.cache.annotation.EnableCaching;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.data.redis.cache.RedisCacheConfiguration;import org.springframework.data.redis.cache.RedisCacheManager;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.RedisSerializationContext;import org.springframework.data.redis.serializer.RedisSerializer;import org.springframework.data.redis.serializer.StringRedisSerializer;import java.time.Duration;@Configuration@EnableCachingpublic class RedisConfig extends CachingConfigurerSupport {    @Value("${spring.cache.redis.time-to-live}")    private Duration timeToLive = Duration.ZERO;        private Jackson2JsonRedisSerializer<Object> serializer() {        // 使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);        ObjectMapper objectMapper = new ObjectMapper();        // 指定要序列化的域,field,get和set,以及修饰符范围,ANY是都有包括private和public        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);        // 指定序列化输入的类型,类必须是非final修饰的,final修饰的类,比如String,Integer等会跑出异常        objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);        jackson2JsonRedisSerializer.setObjectMapper(objectMapper);        return jackson2JsonRedisSerializer;    }    @Bean    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();        redisTemplate.setConnectionFactory(redisConnectionFactory);        // 用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值        redisTemplate.setValueSerializer(serializer());        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();        // 使用StringRedisSerializer来序列化和反序列化redis的key值        redisTemplate.setKeySerializer(stringRedisSerializer);        // hash的key也采用String的序列化方式        redisTemplate.setHashKeySerializer(stringRedisSerializer);        // hash的value序列化方式采用jackson        redisTemplate.setHashValueSerializer(serializer());        redisTemplate.afterPropertiesSet();        return redisTemplate;    }    @Bean    public CacheManager cacheManager(RedisConnectionFactory factory) {        RedisSerializer<String> redisSerializer = new StringRedisSerializer();        // 配置序列化(解决乱码的问题)        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()                // 缓存有效期                .entryTtl(timeToLive)                // 使用StringRedisSerializer来序列化和反序列化redis的key值                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))                // 使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(serializer()))                // 禁用空值                .disableCachingNullValues();        return RedisCacheManager.builder(factory)                .cacheDefaults(config)                .build();    }}

关于“SpringBoot怎么结合Redis实现序列化”这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对“SpringBoot怎么结合Redis实现序列化”知识都有一定的了解,大家如果还想学习更多知识,欢迎关注编程网行业资讯频道。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯