spring redis 序列化,redis springboot实例
00-1010前言配置类配置Jackson2JsonRedisSerializer序列化策略配置RedisTemplate配置缓存策略测试代码完整代码
目录
最近在学习Spring Boot联合Redis的时候,看了一些网上的教程,发现这些教程要么是比较老的,要么是不知道从哪里抄来的,操作起来也有问题。在这里,我想分享一下我最新的写作风格。
默认情况下,Spring为我们提供了一个RedisTemplate来操作Redis,但是RedisTemplate默认配置为使用Java原生序列化。
这种序列化对于操作字符串或数字很有效,但是对于操作对象就不那么方便了。
所以我们需要配置适当的序列化模式。在Spring的官方文档中,官方也建议我们用其他方式序列化。比如JSON
https://docs . spring . io/spring-data/redis/docs/2 . 2 . 5 . release/reference/html/# redis : serializer
前言
00-1010自动配置类的编写将从下面开始。
我使用Jackson2JsonRedisSerializer来序列化对象,所以首先需要一个方法来配置Jackson2JsonRedisSerializer的序列化策略。
private Jackson 2 jsonredisseriazorbject serializer(){//使用Jackson2JsonRedisSerializer对redis的value值进行序列化和反序列化Jackson 2 jsonredisserializer=newjackson 2 jsonredisserializer(object . class);object mapper object mapper=new object mapper();//指定要序列化的域、字段、get和set以及修饰符的范围。ANY同时是私有和公共对象映射器. set visibility(property accessor . all,JSON auto detect . visibility . ANY);//指定序列化输入的类型,并且该类必须是非最终修饰的。最后修饰的类,如String、Integer,将在异常对象映射器之外运行。ActivateDefaultTypeValidator。实例,对象映射程序。默认输入。非_最终);Jackson 2 jsonredisserializer . set object mapper(object mapper);返回jackson2JsonRedisSerializer}这里需要注意的是
objectMapper . activatedefaulttyping(laissezfairsubtypevalidator . instance,object mapper。default typing . NON _ FINAL);这句话非常重要,用于在序列化时将对象的完整类名保存在一起。
之后的序列化结果如下:
[ com . buguagaoshu . redis . model . user ,{name 3360 1 , age 3360 11 , message 3360 awesome}]
如果未设置,则序列化结果如下,并且不会被反序列化。
{ 姓名 : 1 ,年龄 3360 11 ,消息 3360 牛逼 }
一开始在网上搜了一下,发现大部分教程都是因为时间的原因。这个句子使用
对象映射
r.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);但当我把这段代码写入的时候,发现Idea提示我
着是一个过时的方法,由于我当时并不知道这句话的意思,就把这段代码注释了,觉得可能没什么用,但注释后在向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中的数据
数据正常,并且系统也能正常的反序列化了。
完整代码
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;/** * @author Pu Zhiwei {@literal puzhiweipuzhiwei@foxmail.com} * create 2020-03-17 21:08 * 继承 CachingConfigurerSupport,为了自定义生成 KEY 的策略。可以不继承。 */@Configuration@EnableCachingpublic class RedisConfig extends CachingConfigurerSupport { @Value("${spring.cache.redis.time-to-live}") private Duration timeToLive = Duration.ZERO; /** * 配置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); 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序列化的资料请关注盛行IT其它相关文章!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。