Spring Data Redis如何自定义LocalDateTime格式或指定专属转换器?
问题原因
Spring Data Redis 内置的 JSR310 日期转换器默认使用 yyyy-MM-dd'T'HH:mm:ss 格式对 LocalDateTime 类型做序列化/反序列化,你的存量数据是空格分隔的 yyyy-MM-dd HH:mm:ss 格式,因此解析到索引10位置的空格时会抛出格式不匹配异常。
解决方案
根据你的使用场景可选择以下任意一种方案:
方案1:全局自定义Redis转换器(推荐,无需修改实体代码)
该方案会覆盖默认的日期转换规则,全局生效,适配所有LocalDateTime类型字段的读写,和存量数据格式完全兼容。
- 自定义两个转换器,分别处理字节数组转
LocalDateTime、LocalDateTime转字节数组:
import org.springframework.core.convert.converter.Converter; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; // 读取Redis时的转换逻辑 public class BytesToLocalDateTimeConverter implements Converter<byte[], LocalDateTime> { private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); @Override public LocalDateTime convert(byte[] source) { return LocalDateTime.parse(new String(source), FORMATTER); } } // 写入Redis时的转换逻辑,保证新写入数据格式和存量一致 public class LocalDateTimeToBytesConverter implements Converter<LocalDateTime, byte[]> { private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); @Override public byte[] convert(LocalDateTime source) { return source.format(FORMATTER).getBytes(); } }
- 将自定义转换器注册到Redis配置中:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.core.convert.RedisCustomConversions; import java.util.List; @Configuration public class RedisConfig { @Bean public RedisCustomConversions redisCustomConversions() { return new RedisCustomConversions(List.of( new BytesToLocalDateTimeConverter(), new LocalDateTimeToBytesConverter() )); } }
方案2:Jackson序列化场景注解配置
如果你的RedisTemplate使用Jackson2JsonRedisSerializer作为值序列化器,无需编写转换器,直接在实体类对应字段上加注解即可:
import com.fasterxml.jackson.annotation.JsonFormat; import java.time.LocalDateTime; public class YourEntity { @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private LocalDateTime date; }
方案3:单个字段单独适配
如果只有这一个字段格式特殊,不想修改全局规则,可以直接修改实体类字段实现隐式转换:
import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; public class YourEntity { // 存储字段改为String类型,避免触发默认转换器 private String date; private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); // 业务层直接调用该方法获取LocalDateTime类型值 public LocalDateTime getDateAsLocalDateTime() { return date == null ? null : LocalDateTime.parse(date, FORMATTER); } // 业务层直接调用该方法设置LocalDateTime类型值 public void setDateFromLocalDateTime(LocalDateTime localDateTime) { this.date = localDateTime == null ? null : localDateTime.format(FORMATTER); } }
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

