提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
用redise缓存数据的时候,将一个对象列表集合dishList作为值存入,再从中取出时,程序运行时抛出异常:com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Type id handling not implemented for type java.lang.Object (by serializer of type com.fasterxml.jackson.databind.ser.impl.UnsupportedTypeSerializer) (through reference chain: java.util.ArrayList[0]->com.sky.vo.DishVO[“updateTime”])
一、程序前置信息
为了在项目中使用redis,导入Spring Data Redis的maven坐标:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
也配置了配置Redis数据源:
redis:
host: localhost
port: 6379
password: ()
database: ()
配置了RedisConfiguration配置类:
@Bean
public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory){
log.info("======开始创建redis模板对象。。。");
RedisTemplate redisTemplate = new RedisTemplate();
// 设置Redis的连接工厂
redisTemplate.setConnectionFactory(redisConnectionFactory);
// 设置序列化工具
GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
// 设置Redis key 的序列化器
redisTemplate.setKeySerializer(new StringRedisSerializer());
// 两种方式
redisTemplate.setHashKeySerializer(RedisSerializer.string());
// value和 hashValue采用 JSON序列化
redisTemplate.setValueSerializer(jsonRedisSerializer);
redisTemplate.setHashValueSerializer(jsonRedisSerializer);
return redisTemplate;
}
二、问题分析及解决方法
1.问题点:
从redis中取出存入的list对象集合时,程序抛出异常:com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Type id handling not implemented for type java.lang.Object (by serializer of type com.fasterxml.jackson.databind.ser.impl.UnsupportedTypeSerializer) (through reference chain: java.util.ArrayList[0]->com.sky.vo.DishVO[“updateTime”])
2.分析原因:
为了使redis数据再redis图形化工具中显示出正常编码格式数据而不是乱码,我没有使用内置的序列化工具,而是使用了GenericJackson2JsonRedisSerializer,并设置了key和value的序列化器:
代码如下:
// 设置序列化工具
GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
// 设置Redis key 的序列化器
redisTemplate.setKeySerializer(new StringRedisSerializer());
// 两种方式
redisTemplate.setHashKeySerializer(RedisSerializer.string());
// value和 hashValue采用 JSON序列化
redisTemplate.setValueSerializer(jsonRedisSerializer);
redisTemplate.setHashValueSerializer(jsonRedisSerializer);
问题就出现在这里,序列化了后会有问题:Jackson 默认不支持 Java 8的日期/时间类型,包括java.time.LocalDateTime,而存入redis中的对象集合中对象属性含有LocalDateTime的对象属性,序列化为json格式再反序列化时就抛出异常:com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Type id handling not implemented for type java.lang.Object (by serializer of type com.fasterxml.jackson.databind.ser.impl.UnsupportedTypeSerializer) (through reference chain: java.util.ArrayList[0]->com.sky.vo.DishVO[“updateTime”])。
3.解决方法:
用fastjson库把list对象集合转成json格式再存入redis中,取redis值的时候就不会报错了。
再pom.xml中导入依赖:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
在使用redis存数据的地方,将要存入的数据先转成Json格式:
// 原来是直接set(key, dishList),现在:把数据转成Json格式再存
redisTemplate.opsForValue().set(key, JSON.toJSON(dishList));
总结
Jackson 默认不支持 Java 8的日期/时间类型,包括java.time.LocalDateTime,而存入redis中的对象集合中对象属性含有LocalDateTime的对象属性,序列化为json格式再反序列化时就抛出异常:com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Type id handling not implemented for type java.lang.Object (by serializer of type com.fasterxml.jackson.databind.ser.impl.UnsupportedTypeSerializer) (through reference chain: java.util.ArrayList[0]->com.sky.vo.DishVO[“updateTime”])