-
2022-03-30 15:30:10
简述
开发时遇到redis序列化数据报错,这里记录下
错误信息
org.springframework.data.redis.serializer.SerializationException: Cannot serialize; nested exception is org.springframework.core.serializer.support.SerializationFailedException: Failed to serialize object using DefaultSerializer; nested exception is java.lang.IllegalArgumentException: DefaultSerializer requires a Serializable payload but received an object of type [cn.gov.tdt.imgonline.web.template.SessionUser]
问题定位
一般涉及到的常见的redis序列化错误的都是:
1. 序列化器替换,比如换为string serializer
2. 默认redis的序列化器,序列化的对象需要实现Serializable接口
然后这个问题关键词定位:
DefaultSerializer + ‘requires a Serializable payload ’
所以,结论就是 实现Serializable接口
解决
sessionUser实现Serializable接口,并
private static final long serialVersionUID = ...;
更多相关内容 -
Redis 序列化
2021-12-03 14:25:53我们在用redis存储数据的时候,若果默认使用JDK的序列化方式,在Redis桌面花的工具中查看就会使乱码的情况,所以我们需要自定义redis的序列化方式,使用jackson2JsonRedisSerializer,复制下面这段即可 @...我们在用redis存储数据的时候,若果默认使用JDK的序列化方式,在Redis桌面花的工具中查看就会使乱码的情况,所以我们需要自定义redis的序列化方式,使用jackson2JsonRedisSerializer,复制下面这段即可
@Configuration public class RedisConfig { @Bean public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory) { RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(connectionFactory); // 使用Jackson2JsonRedisSerialize替换默认序列化 Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); ObjectMapper objectMapper = new ObjectMapper(); objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(objectMapper); // 设置key和value的序列化规则 redisTemplate.setKeySerializer(new StringRedisSerializer()); redisTemplate.setValueSerializer(jackson2JsonRedisSerializer); redisTemplate.setHashKeySerializer(jackson2JsonRedisSerializer); redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer); redisTemplate.afterPropertiesSet(); return redisTemplate; } }
-
自定义redis序列化和解决穿透问题.docx
2020-04-13 15:20:32应用于java开发 在使用redis缓存时 由于多线程问题造成数据同步延迟 解决redis缓存穿透问题 -
springboot集成redis序列化问题汇总
2022-04-03 22:54:09两种方案中都需要对序列化方式进行设置,否则会出现二进制格式的数据(不论是Redis desktop manager工具还是redis自带客户端黑窗口打开),如果需要查看数据则会影响观感,关于序列化方式设置底层都是对RedisSerializer...1.redis操作方式一:RedisTemplate
2.redis操作方式二:基于Spring Cache
spring中使用redis目前接触的到的有两种方式,一种是使用封装的RedisTemplate工具类;另一种是使用Spring Cache,cache实现方式选择RedisCache.两种方案中都需要对序列化方式进行设置,否则会出现二进制格式的数据(不论是Redis desktop manager工具还是redis自带客户端黑窗口打开),如果需要查看数据则会影响观感,关于序列化方式设置底层都是对RedisSerializer接口进行设置,现分别说明为何出现此问题以及如何避免.
1.redis操作方式一:RedisTemplate
第一种:springboot中常用的redis操作对象:RedisTemplate(StringRedisTemplate属于RedisTemplate子类,此处不做说明)
对于RedisTemplate,如果不指定默认的序列化方式,默认为JdkSerializationRedisSerializer,源码分析如下:
RedisTemplate继承RedisAccessor,RedisAccessor实现InitializingBean接口,RedisTemplate重写afterPropertiesSet,容器加载实例化后进行设置序列化方式属性信息.public class RedisTemplate<K, V> extends RedisAccessor implements RedisOperations<K, V>, BeanClassLoaderAware { // 忽略部分代码 private @Nullable RedisSerializer<?> defaultSerializer; @SuppressWarnings("rawtypes") private @Nullable RedisSerializer keySerializer = null; @SuppressWarnings("rawtypes") private @Nullable RedisSerializer valueSerializer = null; @SuppressWarnings("rawtypes") private @Nullable RedisSerializer hashKeySerializer = null; @SuppressWarnings("rawtypes") private @Nullable RedisSerializer hashValueSerializer = null; @Override public void afterPropertiesSet() { super.afterPropertiesSet(); boolean defaultUsed = false; // 默认序列化方式不设置则使用JdkSerializationRedisSerializer if (defaultSerializer == null) { defaultSerializer = new JdkSerializationRedisSerializer( classLoader != null ? classLoader : this.getClass().getClassLoader()); } if (enableDefaultSerializer) { // 存储key的序列化方式不设置则使用默认序列化方式(不设置则为JdkSerializationRedisSerializer) if (keySerializer == null) { keySerializer = defaultSerializer; defaultUsed = true; } // 存储value的序列化方式不设置则使用默认序列化方式(不设置则为JdkSerializationRedisSerializer) if (valueSerializer == null) { valueSerializer = defaultSerializer; defaultUsed = true; } // 存储HashKey的序列化方式不设置则使用默认序列化方式(不设置则为JdkSerializationRedisSerializer) if (hashKeySerializer == null) { hashKeySerializer = defaultSerializer; defaultUsed = true; } // 存储hashValueSerializer的序列化方式不设置则使用默认序列化方式(不设置则为JdkSerializationRedisSerializer) if (hashValueSerializer == null) { hashValueSerializer = defaultSerializer; defaultUsed = true; } } if (enableDefaultSerializer && defaultUsed) { Assert.notNull(defaultSerializer, "default serializer null and not all serializers initialized"); } if (scriptExecutor == null) { this.scriptExecutor = new DefaultScriptExecutor<>(this); } initialized = true; } // 忽略部分代码 }
RedisSerializer进行存储数据时采用的序列化方式有多种,实现类如下:
最常用的就是json序列化方式:GenericJackson2JsonRedisSerializer或Jackson2JsonRedisSerializer,所以在redis相关配置类型中修改序列化方式即可.
序列化配置修改代码:jackson2JsonRedisSerializer.setObjectMapper(objectMapper); // 设置value的序列化规则和 key的序列化规则 redisTemplate.setKeySerializer(new StringRedisSerializer()); redisTemplate.setValueSerializer(jackson2JsonRedisSerializer); // 设置缓存存储对象 redisTemplate.setHashKeySerializer(new StringRedisSerializer()); redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer); // 设置缓存存储对象 redisTemplate.afterPropertiesSet();
这里贴一下完整redisTemplate配置类,如果有需要可以作为参考:
@Component public class RedisTemplateConfig { @Bean public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) { RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(redisConnectionFactory); // 自定义的string序列化器和fastjson序列化器 StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); // 使用Jackson2JsonRedisSerialize 替换默认序列化 Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); ObjectMapper objectMapper = new ObjectMapper(); objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); // 过滤未知字段 objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); //只序列化必要shiro字段 String [] needSerialize = {"realmPrincipals"}; objectMapper.addMixIn(SimplePrincipalCollection.class, IncludeShiroFields.class); objectMapper.setFilters(new SimpleFilterProvider().addFilter("shiroFilter", SimpleBeanPropertyFilter.filterOutAllExcept(needSerialize))); // 此项必须配置,否则会报java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to XXX objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY); objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); jackson2JsonRedisSerializer.setObjectMapper(objectMapper); // 设置value的序列化规则和 key的序列化规则 redisTemplate.setKeySerializer(new StringRedisSerializer()); redisTemplate.setValueSerializer(jackson2JsonRedisSerializer); // 设置缓存存储对象 redisTemplate.setHashKeySerializer(new StringRedisSerializer()); redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer); // 设置缓存存储对象 redisTemplate.afterPropertiesSet(); return redisTemplate; }
2.redis操作方式二:基于Spring Cache
第二种使用redis方式:Spring Cache
Cache接口支持多种实现,Cache接口实现类如下:
本文对RedisCache进行说明,常用的注解有@Cacheable、@CacheEvict、@CachePut,此处仅对序列化方式进行说明.RedisCache使用需要创建RedisCacheManager,其中需要对RedisCacheConfiguration进行配置.RedisCacheConfiguration设置序列化方式需要借助SerializationPair,源码如下:public RedisCacheConfiguration serializeValuesWith(SerializationPair<?> valueSerializationPair) { Assert.notNull(valueSerializationPair, "ValueSerializationPair must not be null!"); return new RedisCacheConfiguration(this.ttl, this.cacheNullValues, this.usePrefix, this.keyPrefix, this.keySerializationPair, valueSerializationPair, this.conversionService); }
SerializationPair设置序列化方式源码如下:
public interface SerializationPair<T> { static <T> RedisSerializationContext.SerializationPair<T> fromSerializer(RedisSerializer<T> serializer) { Assert.notNull(serializer, "RedisSerializer must not be null!"); return new RedisSerializerToSerializationPairAdapter(serializer); }
从Redistemplate中序列化源码分析可知,RedisSerializer实现类序列化方式使用的是默认jdk.
序列化修改配置:GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer(); RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig(); redisCacheConfiguration = redisCacheConfiguration.serializeValuesWith( RedisSerializationContext .SerializationPair .fromSerializer(genericJackson2JsonRedisSerializer) ).entryTtl(Duration.ofSeconds(seconds));
这里贴一下RedisCacheConfig完整配置,如有需要可以作为参考:
@EnableCaching @Configuration public class RedisCacheConfig { @Bean public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) { RedisCacheManager redisCacheManager = new RedisCacheManager( RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory), // 默认策略,未配置的 key 会使用这个 this.getRedisCacheConfigurationWithTtl(60), // 指定 key 策略 this.getRedisCacheConfigurationMap() ); redisCacheManager.setTransactionAware(true); return redisCacheManager; } private Map<String, RedisCacheConfiguration> getRedisCacheConfigurationMap() { Map<String, RedisCacheConfiguration> redisCacheConfigurationMap = new HashMap<>(16); return redisCacheConfigurationMap; } private RedisCacheConfiguration getRedisCacheConfigurationWithTtl(Integer seconds) { // 指定使用GenericJackson2JsonRedisSerializer序列化方式 GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer(); RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig(); redisCacheConfiguration = redisCacheConfiguration.serializeValuesWith( RedisSerializationContext .SerializationPair .fromSerializer(genericJackson2JsonRedisSerializer) ).entryTtl(Duration.ofSeconds(seconds)); return redisCacheConfiguration; }
以上为自己总结梳理,如有异议,欢迎评论区评论交流!
-
Springboot中redis序列化和反序列化配置
2022-01-21 14:55:28springboot中redis序列化与反序列化目录
1.说明
在java项目中使用redis时候是通过字节流的方式进行存取的,所以不论是查看还是获取都需要转换成java对象,这样会更加方便
2.配置
1.引入依赖
这里本来想要使用的org.springframework.boot的版本,但是会出现问题,可能是版本匹配问
<spring-boot-starter-redis-version>1.4.7.RELEASE</spring-boot-starter-redis-version> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-redis</artifactId> <version>${spring-boot-starter-redis-version}</version> </dependency>
所以建议大家使用这个依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.72</version> </dependency>
2.添加配置类
可以参考下面创建配置类 RedisConfiguration
package com.hhmt.flowalliance.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; /** * 辉煌明天 * FileName: RedisConfiguration * Author: huachun * email: huachun_w@163.com * Date: 2021/11/5 15:57 * Description: Redis配置类 */ @Configuration public class RedisConfiguration { @Bean @SuppressWarnings("all") public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) { RedisTemplate<String, Object> template = new RedisTemplate<String, Object>(); 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(); template.setKeySerializer(stringRedisSerializer); template.setHashKeySerializer(stringRedisSerializer); template.setValueSerializer(jackson2JsonRedisSerializer); template.setHashValueSerializer(jackson2JsonRedisSerializer); template.afterPropertiesSet(); return template; } }
添加配置文件
写好自己连接redis的参数信息
spring: application: name: redis: client-name: redis host: port: password: jedis: pool: max-active: 8 max-wait: -1 max-idle: 8 min-idle: 0 connect-timeout: 3000
3.测试实体对象
创建实体类User用于测试
package com.hhmt.flowalliance.model; import lombok.Data; /** * 辉煌明天 * FileName: User * Author: huachun * email: huachun_w@163.com * Date: 2022/1/21 14:15 * Description: */ @Data public class User { private String name; private String age; }
4.测试集合
注意:这里使用的是set方法,对,你没看错,是存储字符串的set方法
如果使用操作集合的方法会变成存进去和拿出来的数据会变成字符串,有兴趣的朋友可以尝试,也可能是我方法不对,如果感兴趣的朋友欢迎在下方和我留言互动.
3.测试
测试实体对象
测试存储List对象
在这里向大家推荐一款好用的redis界面化操作工具,好看也好用
原文可参考:springboot整合redis序列化(3步搞定)_潘哒哒曦的博客-CSDN博客_springboot序列化
-
Redis序列化和反序列化
2021-03-06 23:56:59在回答您的问题之前,我想给您一些背景知识,序列化运行时与每个可序列化的类关联一个版本号,称为serialVersionUID,在反序列化期间使用该版本号来验证序列化对象的发送者和接收者是否已加载了该对象的与序列化兼容... -
redis序列化_redis乱码_redis对象序列化
2021-12-01 18:18:40设置redis的序列化,防止对象乱码, redis的hash数据类型,序列化方式默认使用的是对象序列化,会显示乱码 redisTemplate.setKeySerializer(new StringRedisSerializer()); //hash内部对象序列化,解决对象乱码 ... -
SpringBoot Redis配置Fastjson进行序列化和反序列化实现
2020-10-16 03:12:55主要介绍了SpringBoot Redis配置Fastjson进行序列化和反序列化实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧 -
Springboot集成Redis项目中Redis序列化配置
2022-02-08 21:32:19企业级项目中Redis序列化配置方案 -
Redis序列化的几种方式
2019-12-12 15:03:36Redis序列化的几种方式 1.什么是Redis Redis是用C语言开发的一个开源的高性能键值对(key-value)数据库。它通过提供多种键值数据类型来适应不同场景下的存储需求,目前为止Redis支持的键值数据类型如下: 1、 字符... -
Shiro-集成Redis序列化失败报错解决
2021-06-17 23:41:58Shiro-集成Redis序列化失败报错解决 最近在使用Shiro集成Redis,使用分布式缓存时序列化与序列化时报错,报错信息如 Cannot serialize; nested exception is org.springframework.core.serializer.support.... -
重写Redis序列化方式,redis可视化工具不乱码
2022-02-10 14:57:26重写Redis序列化方式,redis可视化工具不乱码 -
redis序列化存入数据后读取时少内容
2022-04-01 15:18:45所以,在序列化进redis后的key和value都是乱码,如: 这还不是重点,重点是,再从redis中读取的时候,读取回来的数据就缺少内容了!比如我的实体类是Session2: package com.test.test; impo. -
redis 序列化 报错
2021-09-13 15:15:54nested exception is java.lang.ClassNotFoundException 1 对象序列化存入redis后,包名被修改,导致取出对象反序列化时包名不一致,报错 解决方案:清空redis 2 序列化与反序列化方式不对称也可能导致报错 解决... -
Redis序列化方式
2021-04-25 13:19:47序列化后的结果非常庞大,是JSON格式的5倍左右,这样就会消耗redis服务器的大量内存 2. StringRedisSerializer 是StringRedisTemplate默认的序列化方式,key和value都会采用此方式进行序列化,是被推荐使用的,对... -
springboot集成redis序列化配置
2021-01-12 15:45:511.当我们的springboot集成了redis,然后通过springboot程序往redis设置信息,做缓存使用,如果没有使用序列化的时候,也是可以set进去的,不过是这样子的 库里的值: value信息: 看到的都是这样子的,为什么... -
redis序列化key、value
2021-09-17 13:14:45redis常见的序列化方式有: 使用redistemplate操作redis,发现value值保存的为一个二进制,但是不影响程序读写 经查阅资料,是RedisTemplate默认序列化方式用的是JdkSerializationRedisSerializer,此时我将... -
redis序列化原因及各种序列化情况划分
2021-01-17 12:14:10在实际开发中,当我们要往redis中存对象时,都要进行序列化的。 当然,如果我们把对象给转换json字符串,此时存储的相当于是字符串。不序列化并不影响正常运行 但是,通常我们都要把我们创建的对象给序列化。 假如... -
关于SpringRedis序列化器的问题
2022-03-11 14:57:55后面排查是同事提供了一个rpc接口,这个接口有修改RedisTemplate 序列化器的代码,调完那个rpc接口,再调这个接口就会出现序列化的问题。然后进行代码自测,发现里面存在一些以前没注意的问题。 RedisTemplate的... -
Springboot中redis序列化问题分析
2019-04-23 18:18:04研究原因: springboot中使用redis获取数据后,转换成对象时, ... 最后发现是因为redis的序列化方式引起的。所以就对redis序列化的方式做一下分析: 1、springboot中redis存储数据序列化方式,常用的有以... -
java对象传入Redis序列化问题
2022-03-18 16:02:59此时需要使用RedisSerializer进行序列化和反序列化 代码如下 @Configuration public class RedisConfig { @Bean public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory .. -
redis序列化_redis返回null
2021-12-14 09:42:36redis序列化配置 解决了,redis有值,但是获取返回null的问题 原因:启动类启动没有加载到redis的相关配置 redis序列化配置 @Configuration @EnableCaching public class RedisConfig extends ... -
关于redis序列化的问题
2022-03-31 12:00:51工作中遇到一个reids序列化问题,当你存储map的时候,传统的:GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer(); // 采用Json序列化 redisTemplate.... -
解决redis序列化java8 LocalDateTime
2020-06-16 15:56:35文章目录redis 序列化问题解决方案1. 使用注解的方式2. 使用全局配置文件 redis 序列化问题 在 JDK8 中 官方提出 LocalDateTime 的时间格式,因为他是线程安全的, 在我们的业务中,我们需要把 一些数据存到缓存... -
一键解决redis序列化问题
2020-07-28 11:55:24一、spring boot 集成Redis方法 <!-- redis --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> &... -
Redis序列化乱码问题解决
2021-05-07 22:40:22使用的是 Jackson2JsonRedisSerializer 来对对象进行序列化 其他的步骤就不罗嗦了,直接贴config类 package com.lzx.config; import com.fasterxml.jackson.annotation.JsonAutoDetect; import ... -
Redis序列化存储及日期格式的问题处理
2022-02-23 13:34:51Redis序列化存储及日期格式的问题处理 -
配置Redis序列化方式不生效问题
2021-12-14 10:38:38今天进行redis配置没有注意redis设置序列化方式的方法名称,导致redis序列化一直不成功。 @Configuration public class RedisConfig { @Bean public RedisTemplate<Object, Object> redisTemplate... -
Redis 序列化值,多了双引号问题
2021-09-27 14:25:09修改相应的序列化值即可 -
redis序列化方式
2019-04-25 14:38:00redis序列化方式 (内容复制别人的博客,留作学习笔记) spring-data-redis的序列化类有下面这几个: GenericToStringSerializer: 可以将任何对象泛化为字符串并序列化 Jackson2JsonRedisSerializer: 跟...