Redis SpringCache——LocalDateTime导致 Java 8 date/time type `java.time.LocalDateTime` not supported

缓存序列化异常——LocalDateTime

  • 缓存序列化异常——LocalDateTime
    • 前言
    • 步骤
      • 1.确认序列化
      • 2.确认数据库连接指定时区与我们序列化时区相同
      • 3.确认添加依赖
      • 4.更改SpringCache的序列化器

缓存序列化异常——LocalDateTime

前言

这个问题是我在使用SpringCache进行Redis序列化导致的问题,解决方法分为多个步骤,请大家仔细排查,错误产生方式可能不同

步骤

1.确认序列化

我们首先确认我们要进行序列化的数据,例如如下,我们要确定我们的类要实现Serializable接口,确保涉及到LocalDateTime的属性必须指定序列化和反序列化的注解,分别为

    @JsonSerialize(using = LocalDateTimeSerializer.class)
    @JsonDeserialize(using = LocalDateTimeDeserializer.class)

完整示例:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class KnowReposMenuTreeVO implements Serializable {
    @JsonSerialize(using = ToStringSerializer.class)
    private Long menuId;

    private String menuName;

    private String url;

    private String icon;

    private String author;

    private Integer orderNum;
    @JsonFormat(pattern = "yyyy-MM-dd",timezone = "GMT+8")
    @JsonSerialize(using = LocalDateTimeSerializer.class)
    @JsonDeserialize(using = LocalDateTimeDeserializer.class)
    private LocalDateTime createTime;
    @JsonFormat(pattern = "yyyy-MM-dd",timezone = "GMT+8")
    @JsonSerialize(using = LocalDateTimeSerializer.class)
    @JsonDeserialize(using = LocalDateTimeDeserializer.class)
    private LocalDateTime updateTime;

    private ArrayList<KnowReposMenuTreeVO> child;
}

2.确认数据库连接指定时区与我们序列化时区相同

我们可以看到,我还指定了一个序列化注解@JsonFormat(pattern = "yyyy-MM-dd",timezone = "GMT+8"),这里我们指定了timezone也就是时区,指定为东八区!,那么我们的数据库连接时我们也要确保为东八区时间

url: jdbc:mysql://localhost:3306/routerboot_menu?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=GMT+8&zeroDateTimeBehavior=CONVERT_TO_NULL&allowPublicKeyRetrieval=true

或者你可以指定同为Asia/Shanghai这样指定城市
但这只是一个建议,因为根据我的测试,即使不同也不会影响

3.确认添加依赖

如下使用的是Jaskson序列化时间的依赖,建议加上,但即使加上你可能依然会报错,如果是这样请继续看下去

        <dependency>
            <groupId>com.fasterxml.jackson.datatype</groupId>
            <artifactId>jackson-datatype-jsr310</artifactId>
        </dependency>

4.更改SpringCache的序列化器

以下代码是自定义的SpringCacheRedisConfig配置,对Redis的序列化键值方式进行修改,键使用了StringRedisSerializer(),值则使用了GenericFastJsonRedisSerializer()这是FastJson2的Redis序列化方式,根据我的测试,原先我使用的是GenericJackson2JsonRedisSerializer性能上比较低,接口首次访问序列化整体时间约3s,修改后平均为700ms,性能提升近5倍

//@ConfigurationProperties(prefix = "spring.cache")
//CacheProperties.class
@EnableConfigurationProperties(CacheProperties.class)
@Configuration
@EnableCaching
public class RWRedisConfig {
    

    @Bean
    RedisCacheConfiguration redisCacheConfiguration(CacheProperties cacheProperties){
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
        config = config.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()));
        config = config.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericFastJsonRedisSerializer()));
       //获取redis配置
        final CacheProperties.Redis redisProperties = cacheProperties.getRedis();
        if (redisProperties.getTimeToLive() != null) {
            config = config.entryTtl(redisProperties.getTimeToLive());
        }
        if (redisProperties.getKeyPrefix() != null) {
            config = config.prefixCacheNameWith(redisProperties.getKeyPrefix());
        }
        if (!redisProperties.isCacheNullValues()) {
            config = config.disableCachingNullValues();
        }
        if (!redisProperties.isUseKeyPrefix()) {
            config = config.disableKeyPrefix();
        }
        return config;
    }
}

你可能感兴趣的:(笔记,redis,#,SSM框架,redis,java,数据库)