这篇文章主要讲解了“如何将没有实现Serializable的类存储到Redis中”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“如何将没有实现Serializable的类存储到Redis中”吧!
你有没有遇到过这种情况,需要将实例对象存储到Redis
中,但是类的字段包含第三方依赖中的类并且此类没有 implements Serializable
。 执行时就会报没有序列化的错:
Caused by: java.lang.IllegalArgumentException: DefaultSerializer requires a Serializable payload but received an object of type [com.entity.UserEntity]
at org.springframework.core.serializer.DefaultSerializer.serialize(DefaultSerializer.java:43)
at org.springframework.core.serializer.Serializer.serializeToByteArray(Serializer.java:56)
at org.springframework.core.serializer.support.SerializingConverter.convert(SerializingConverter.java:60)
... 54 more
有三种方法如下
ObjectHashMapper
使用对象到哈希映射。
需存redis的类如下:
用户类
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class UserEntity {
/**
* 用户名
*/
private String username;
/**
* 年龄
*/
private Integer age;
/**
* 所属部门
*/
private Department department;
/**
* 创建时间
*/
private Date createTime;
/**
* 手机号码
*/
private List<String> phoneNumber;
/**
* 爱好
*/
private Map<String, Object> hobby;
}
部门类
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Department {
/**
* 部门id
*/
private String depId;
/**
* 部门名称
*/
private String depName;
/**
* 父级部门
*/
private String parentId;
}
注意:上面两个类都没有实现序列化
通过ObjectHashMapper的toHash和fromHash实现
List<String> phoneNumbers = new ArrayList<>();
phoneNumbers.add("13016541724");
phoneNumbers.add("18826173452");
Map<String, Object> hobbys = new HashMap<>();
hobbys.put("运行", "打羽毛球");
hobbys.put("电影", "看电影");
UserEntity userEntity = UserEntity.builder().username("张三").age(18).department(
Department.builder().depId("djinefn213445nkqk").depName("研发中心").parentId("ncdjkn3j4njndcinw").build()
).createTime(new Date()).phoneNumber(phoneNumbers).hobby(hobbys)
.build();
ObjectHashMapper objectHashMapper = new ObjectHashMapper();
Map<byte[], byte[]> map = objectHashMapper.toHash(userEntity);
redisTemplate.opsForHash().put("TEST_OBJECT", "a", map);
Map<byte[], byte[]> map1 = (Map<byte[], byte[]>) redisTemplate.opsForHash().get("TEST_OBJECT", "a");
UserEntity userEntityRes = (UserEntity) objectHashMapper.fromHash(map1);
Jackson2HashMapper
通过使用FasterXMLJackson
为域对象提供Redis
哈希映射。可以将顶级属性映射为哈希字段名,也可以选择展平结构。简单类型映射到简单值。复杂类型(嵌套对象、集合、映射等)表示为嵌套JSON。Jackson2HashMapper
平展为所有嵌套属性创建单独的哈希条目,并尽可能将复杂类型解析为简单类型。
List<String> phoneNumbers = new ArrayList<>();
phoneNumbers.add("13016541724");
phoneNumbers.add("18826173452");
Map<String, Object> hobbys = new HashMap<>();
hobbys.put("运行", "打羽毛球");
hobbys.put("电影", "看电影");
UserEntity userEntity = UserEntity.builder().username("张三").age(18).department(
Department.builder().depId("djinefn213445nkqk").depName("研发中心").parentId("ncdjkn3j4njndcinw").build()
).createTime(new Date()).phoneNumber(phoneNumbers).hobby(hobbys)
.build();
Jackson2HashMapper jackson2HashMapper = new Jackson2HashMapper(true);
Map<String, Object> map = jackson2HashMapper.toHash(userEntity);
redisTemplate.opsForHash().put("TEST_OBJECT", "a", map);
Map<String, Object> map1 = (Map<String, Object>) redisTemplate.opsForHash().get("TEST_OBJECT", "a");
UserEntity userEntityRes = (UserEntity) jackson2HashMapper.fromHash(map1);
BeanUtilsHashMapper
使用Spring的BeanUtils。
List<String> phoneNumbers = new ArrayList<>();
phoneNumbers.add("13016541724");
phoneNumbers.add("18826173452");
Map<String, Object> hobbys = new HashMap<>();
hobbys.put("运行", "打羽毛球");
hobbys.put("电影", "看电影");
UserEntity userEntity = UserEntity.builder().username("张三").age(18).department(
Department.builder().depId("djinefn213445nkqk").depName("研发中心").parentId("ncdjkn3j4njndcinw").build()
).createTime(new Date()).phoneNumber(phoneNumbers).hobby(hobbys)
.build();
BeanUtilsHashMapper beanUtilsHashMapper = new BeanUtilsHashMapper(UserEntity.class);
Map<String, Object> map = beanUtilsHashMapper.toHash(userEntity);
redisTemplate.opsForHash().put("TEST_OBJECT", "a", map);
Map<String, Object> map1 = (Map<String, Object>) redisTemplate.opsForHash().get("TEST_OBJECT", "a");
UserEntity userEntityRes = (UserEntity) beanUtilsHashMapper.fromHash(map1);
运行会报
Caused by: org.apache.commons.beanutils.ConversionException: Can't convert value '' to type interface java.util.List
at org.apache.commons.beanutils.converters.AbstractConverter.conversionException(AbstractConverter.java:474)
at org.apache.commons.beanutils.converters.StringConverter.convertToType(StringConverter.java:96)
at org.apache.commons.beanutils.converters.AbstractConverter.handleMissing(AbstractConverter.java:312)
... 58 more
从报错中可以看出,List
为interface
,无法转换。将List
改为ArrayList
,Map改为HashMap
再执行报如下错误
Caused by: org.apache.commons.beanutils.ConversionException: Can't convert value '' to type class java.util.ArrayList
at org.apache.commons.beanutils.converters.AbstractConverter.conversionException(AbstractConverter.java:474)
at org.apache.commons.beanutils.converters.StringConverter.convertToType(StringConverter.java:96)
at org.apache.commons.beanutils.converters.AbstractConverter.handleMissing(AbstractConverter.java:312)
... 58 more
排查会发现,phoneNumber的两个手机号码toHash后变成了一个手机号码
这是BeanUtilsHashMapper
的一个缺陷。
感谢各位的阅读,以上就是“如何将没有实现Serializable的类存储到Redis中”的内容了,经过本文的学习后,相信大家对如何将没有实现Serializable的类存储到Redis中这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。