报错信息
org.springframework.data.redis.serializer.SerializationException: Could not read JSON: Cannot construct instance of `java.time.LocalDateTime` (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
at [Source: (byte[])"{"@class":"com.petzm.manage.admin.domain.Operator","id":1,"operatorAccount":"123","operatorPassword":"297254e9bfe0b8f39c682eda30bb9be0","operatorMobile":"13300000000","operatorName":"测试1","creator":"系统测试","operatorType":1,"departmentId":3,"positionId":1,"typeBelongId":1,"parentId":0,"remark":"测试账号1","createTime":{"month":"APRIL","year":2020,"dayOfMonth":13,"dayOfWeek":"MONDAY","dayOfYear":104,"hour":19,"minute":19,"nano":0,"second":19,"monthValue":4,"chronology":{"@class":"ja"[truncated 325 bytes]; line: 1, column: 336] (through reference chain: com.petzm.manage.admin.domain.Operator["createTime"]); nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `java.time.LocalDateTime` (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
at [Source: (byte[])"{"@class":"com.petzm.manage.admin.domain.Operator","id":1,"operatorAccount":"123","operatorPassword":"297254e9bfe0b8f39c682eda30bb9be0","operatorMobile":"13300000000","operatorName":"测试1","creator":"系统测试","operatorType":1,"departmentId":3,"positionId":1,"typeBelongId":1,"parentId":0,"remark":"测试账号1","createTime":{"month":"APRIL","year":2020,"dayOfMonth":13,"dayOfWeek":"MONDAY","dayOfYear":104,"hour":19,"minute":19,"nano":0,"second":19,"monthValue":4,"chronology":{"@class":"ja"[truncated 325 bytes]; line: 1, column: 336] (through reference chain: com.petzm.manage.admin.domain.Operator["createTime"])
查看错误后发现是redis中的数据被jackson2反序列化数据时LocalDateTime类型转换异常,原因是:Jackson2在序列化LocalDateTime时输出的不是普通的字符串时间格式,而是如下所示的格式(普通时间格式:yyyy:MM:dd HH:mm:ss)。
"createTime": {
"month": "APRIL",
"year": 2020,
"dayOfMonth": 13,
"dayOfWeek": "MONDAY",
"dayOfYear": 104,
"hour": 19,
"minute": 19,
"nano": 0,
"second": 19,
"monthValue": 4,
"chronology": {
"@class": "java.time.chrono.IsoChronology",
"id": "ISO",
"calendarType": "iso8601"
}
所以问题在于jackson2反序列化LocalDateTime时格式存在问题,需要指定redis序列化模板
@Configuration
public class RedisConfiguration {
/**
* 配置存储时的字符转换
*/
@Bean
public RedisTemplate<String, Serializable> redisTemplate(LettuceConnectionFactory connectionFactory) {
RedisTemplate<String, Serializable> redisTemplate = new RedisTemplate<>();
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setConnectionFactory(connectionFactory);
//下面代码解决LocalDateTime序列化与反序列化不一致问题
Jackson2JsonRedisSerializer<Object> j2jrs = new Jackson2JsonRedisSerializer<>(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
// 解决jackson2无法反序列化LocalDateTime的问题
om.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
om.registerModule(new JavaTimeModule());
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
j2jrs.setObjectMapper(om);
// 序列化 value 时使用此序列化方法
redisTemplate.setValueSerializer(j2jrs);
redisTemplate.setHashValueSerializer(j2jrs);
return redisTemplate;
}
}
配置后正常转换
"createTime": "2020-04-13T19:19:19",