持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第7天,点击查看活动详情
1. Redis存放LocalDateTime问题
今天在自己做项目的时候突然遇到了这个问题,使用
RedisTemplate
存放用户登录数据的时候有一个值是LocalDateTime类型的,存放的时候好好的,可以正常进入,但是在Redis中是以数组方式存在的
[
"net.lesscoding.entity.User",
{
"currentPage": 1,
"pageSize": 10,
"total": null,
"data": null,
"createBy": null,
"creatorName": null,
"createTime": null,
"updateBy": null,
"updateName": null,
"updateTime": null,
"delFlag": null,
"id": 1,
"username": "admin",
"password": "6fc982f2020767904a68e2954dca32a4",
"avatar": null,
"email": null,
"loginErrorTime": 0,
"locked": false,
"lastLoginTime": {
"date": {
"year": 2022,
"month": "OCTOBER",
"day": 28,
"dayOfMonth": 28,
"monthValue": 10,
"dayOfWeek": "FRIDAY",
"era": [
"java.time.chrono.IsoEra",
"CE"
],
"dayOfYear": 301,
"leapYear": false,
"chronology": {
"id": "ISO",
"calendarType": "iso8601"
},
"prolepticMonth": 24273
},
"time": {
"hour": 20,
"minute": 42,
"second": 48,
"nano": 0
},
"month": "OCTOBER",
"year": 2022,
"dayOfMonth": 28,
"hour": 20,
"minute": 42,
"monthValue": 10,
"nano": 0,
"second": 48,
"dayOfWeek": "FRIDAY",
"dayOfYear": 301,
"chronology": [
"java.time.chrono.IsoChronology",
{
"id": "ISO",
"calendarType": "iso8601"
}
]
},
"token": null,
"roleList": [
"java.util.ArrayList",
[]
],
"menuList": [
"java.util.ArrayList",
[]
]
}
]
- 原来的代码
package net.lesscoding.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import org.springframework.beans.factory.annotation.Autowired; 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.connection.lettuce.LettuceConnectionFactory; 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 zhaojinhui
-
@date 2021/3/13 16:18
-
@apiNote */ @EnableCaching @Configuration public class RedisConfig extends CachingConfigurerSupport {
@Autowired private RedisConnectionFactory redisConnectionFactory;
/* 此序列化方法localDateTime存入 redis时是数组,反序列化会报错 @Bean public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) { RedisTemplate<String, Object> template = new RedisTemplate<>(); RedisSerializer redisSerializer = new StringRedisSerializer(); 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); template.setConnectionFactory(factory); //key序列化方式 template.setKeySerializer(redisSerializer); //value序列化 template.setValueSerializer(jackson2JsonRedisSerializer); //value hashmap序列化 template.setHashValueSerializer(jackson2JsonRedisSerializer); return template; }*/
@Bean public RedisTemplate<String,Object> redisTemplate(LettuceConnectionFactory connectionFactory){ RedisTemplate<String,Object> redisTemplate = new RedisTemplate<>(); // 设置连接池 redisTemplate.setConnectionFactory(connectionFactory);
// 解决key的序列化方案 StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); redisTemplate.setKeySerializer(stringRedisSerializer); //解决value的序列化方案 Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class); //处理LocalDateTime类型的序列化 ObjectMapper objectMapper = new ObjectMapper(); //将当前对象的类型存放到redis中 objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,ObjectMapper.DefaultTyping.NON_FINAL); objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); objectMapper.registerModule(new JavaTimeModule()); jackson2JsonRedisSerializer.setObjectMapper(objectMapper); redisTemplate.setValueSerializer(jackson2JsonRedisSerializer); return redisTemplate;
}
@Bean public CacheManager cacheManager(RedisConnectionFactory factory) { RedisSerializer redisSerializer = new StringRedisSerializer(); 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); // 配置序列化(解决乱码的问题),过期时间600秒 RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig() .entryTtl(Duration.ofSeconds(600)) .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer)) .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer)) .disableCachingNullValues(); RedisCacheManager cacheManager = RedisCacheManager.builder(factory) .cacheDefaults(config) .build(); return cacheManager; }
}