Redis存放LocalDateTime序列化问题

561 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 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; }

}