最近在项目中发现之前同事在使用Redis存储对象的时候,给日期字段存了两种不同的日期格式,进而导致查询时反序列化报错,因此写了一个注解配置类来自定义反序列化的方式。
kotlin
/**
* LocalDateTime反序列化,下方的LocalDate同理,可以略过
*/
class LocalDateTimeDeserializer : JsonDeserializer<LocalDateTime>() {
override fun deserialize(p: JsonParser, ctxt: DeserializationContext): LocalDateTime {
val dateStr = p.text
// 根据日期字符串的长度来判断对应的格式
return when {
// 类似:2024-02-06 10:00:00
dateStr.length == 19 -> LocalDateTime.parse(dateStr, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
// 类似:2024-02-06T10:00:00.988+08:00
dateStr.length >= 26 -> LocalDateTime.parse(dateStr, DateTimeFormatter.ISO_OFFSET_DATE_TIME)
else -> throw IllegalArgumentException("Invalid date format: $dateStr")
}
}
}
/**
* LocalDate反序列化
*/
class LocalDateDeserializer : JsonDeserializer<LocalDate>() {
override fun deserialize(p: JsonParser, ctxt: DeserializationContext): LocalDate {
val dateStr = p.text
return when {
dateStr.length == 10 -> LocalDate.parse(dateStr, DateTimeFormatter.ISO_LOCAL_DATE)
dateStr.length >= 26 -> LocalDate.parse(dateStr, DateTimeFormatter.ISO_OFFSET_DATE_TIME)
else -> throw IllegalArgumentException("Invalid date format: $dateStr")
}
}
}
接着只需要在对应的日期字段上加上注解即可。
@JsonDeserialize
注解位于com.fasterxml.jackson.databind.annotation
包下(Jackson
)
kotlin
@JsonDeserialize(using = LocalDateTimeDeserializer::class)
var createTime: LocalDateTime? = null
这只是临时的解决方案,正确的做法是在一开始保存到Redis的时候就统一好日期格式,尽量不要出现多种格式百花齐放的情况。