一、问题
当我准备在boot程序启动时对业务对象进行初始化存储在redis中我发现服务启动报错为:Could not write JSON: Java 8 date/time type java.time.LocalDateTime
not supported by default: add Module “com.fasterxml.jackson.datatype:jackson-datatype-jsr310” to enable handling
当时盲猜:业务对象LocalDateTime类型的属性在序列化报错
二、实际原因
Jackson库在默认情况下不支持Java8的LocalDateTime类型的序列化和反序列化。
三、解决方法
1.添加jackson依赖
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>2.12.5</version>
</dependency>
2.修改RedisConfig
@Configuration
public class RedisConfig {
@Bean
public RedisSerializer<Object> redisSerializer() {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
// 必须设置,否则无法将JSON转化为对象,会转化成Map类型
objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);
// 自定义ObjectMapper的时间处理模块
JavaTimeModule javaTimeModule = new JavaTimeModule();
javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern("HH:mm:ss")));
javaTimeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern("HH:mm:ss")));
objectMapper.registerModule(javaTimeModule);
// 禁用将日期序列化为时间戳的行为
objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
//创建JSON序列化器
return new Jackson2JsonRedisSerializer<>(objectMapper, Object.class);
}
/**
* 自定义 RedisTemplate
* <p>
* 修改 Redis 序列化方式,默认 JdkSerializationRedisSerializer
*
* @param redisConnectionFactory {@link RedisConnectionFactory}
* @return {@link RedisTemplate}
*/
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
// 使用 String 序列化 key
redisTemplate.setKeySerializer(RedisSerializer.string());
redisTemplate.setHashKeySerializer(RedisSerializer.string());
// 使用自定义的 JSON 序列化器(支持 LocalDateTime)
redisTemplate.setValueSerializer(redisSerializer());
redisTemplate.setHashValueSerializer(redisSerializer());
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
}