Spring 使用 Redis 的数据:如何使用不同的 LocalDateTime 格式或不同的转换器?

Spring Data with Redis: How do I use a different LocalDateTime format or a different convertor?

我的数据库中有字段 日期 的数据,格式如下:2021-09-21 11:25:36。 Redis字段是TEXT类型。

当我试图从数据库的 date 字段中读取数据时,出现以下异常:

Failed to convert from type [byte[]] to type [java.time.LocalDateTime] for value '{50, 48, 50, 49, 45, 48, 57, 45, 50, 49, 32, 49, 49, 58, 50, 53, 58, 51, 54}'; nested exception is java.time.format.DateTimeParseException: Text '2021-09-21 11:25:36' could not be parsed at index 10
org.springframework.core.convert.ConversionFailedException: Failed to convert from type [byte[]] to type [java.time.LocalDateTime] for value '{50, 48, 50, 49, 45, 48, 57, 45, 50, 49, 32, 49, 49, 58, 50, 53, 58, 51, 54}'; nested exception is java.time.format.DateTimeParseException: Text '2021-09-21 11:25:36' could not be parsed at index 10
(...)
Caused by: java.time.format.DateTimeParseException: Text '2021-09-21 11:25:36' could not be parsed at index 10
    at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2050)
    at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1952)
    at java.base/java.time.LocalDateTime.parse(LocalDateTime.java:493)
    at java.base/java.time.LocalDateTime.parse(LocalDateTime.java:478)
    at org.springframework.data.redis.core.convert.Jsr310Converters$BytesToLocalDateTimeConverter.convert(Jsr310Converters.java:113)
    at org.springframework.data.redis.core.convert.Jsr310Converters$BytesToLocalDateTimeConverter.convert(Jsr310Converters.java:108)
    at org.springframework.core.convert.support.GenericConversionService$ConverterAdapter.convert(GenericConversionService.java:386)
    at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:41)
    ... 142 more

如何为实体中的此字段分配不同的转换器或注释我的 LocalDateTime 格式与预期格式不同?我目前的假设是问题出在日期和时间之间缺少 'T',但我几乎没有可能更改数据库中的数据。

您可以使用 Jackson json 格式 com.fasterxml.jackson.annotation.JsonFormat

@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime timestamp;

稍后我自己使用 RedisCustomConverters:

找到了答案

这个bean是必需的:

    @Bean
    public RedisCustomConversions redisCustomConversions(BytesToLocalDateTimeConverter bytesToLocalDateTimeConverter) {
        return new RedisCustomConversions(List.of(bytesToLocalDateTimeConverter));
    }

结合这个自定义转换器:

@Component
@ReadingConverter
public class BytesToLocalDateTimeConverter implements Converter<byte[], LocalDateTime> {

    @Override
    public LocalDateTime convert(final byte[] source) {
        return LocalDateTime.parse(new String(source), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
    }
}