SpringBoot中Redis解决LocalDateTime序列化与反序列化不一致问题

本文介绍了在SpringBoot应用中LocalDateTime类型数据的序列化与反序列化问题,通过配置Redis的Jackson2JsonRedisSerializer并解决相关设置,确保数据在不同环境下的一致性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 前言

        在SpringBoot应用中,数据的序列化和反序列化是关键环节。然而,对于LocalDateTime类型的数据,有时会遇到序列化与反序列化不一致的问题。这主要是由于不同的时区或格式差异所导致。为了解决这一问题,我们可以借助Redis的强大功能。Redis提供了日期和时间的序列化和反序列化方法,确保了在不同环境下的数据一致性。通过配置合理的序列化策略,我们能够确保LocalDateTime数据在SpringBoot应用中的准确处理。这样,无论在存储、传输还是处理数据时,都能够确保数据的一致性和准确性。

一、Redis配置类

        只需配置以下配置即可解决LocalDateTime序列化与反序列化不一致问题

@Configuration
public class RedisConfig {

	@Bean
	public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
		RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
		redisTemplate.setConnectionFactory(factory);
		Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
		ObjectMapper mapper = new ObjectMapper();
		mapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
		jackson2JsonRedisSerializer.setObjectMapper(mapper);
		StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
		redisTemplate.setKeySerializer(stringRedisSerializer);
		redisTemplate.setHashKeySerializer(stringRedisSerializer);
		redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
		redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
		redisTemplate.afterPropertiesSet();

		//下面代码解决LocalDateTime序列化与反序列化不一致问题
		Jackson2JsonRedisSerializer<Object> j2jrs = new Jackson2JsonRedisSerializer<>(Object.class);
		ObjectMapper om = new ObjectMapper();
		om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
		// 解决jackson2无法反序列化LocalDateTime的问题
		om.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
		om.registerModule(new JavaTimeModule());om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);j2jrs.setObjectMapper(om);
		// 序列化 value 时使用此序列化方法
		redisTemplate.setValueSerializer(j2jrs);
		redisTemplate.setHashValueSerializer(j2jrs);
		return redisTemplate;
	}
}

<think>我们参考用户提供的引用内容,特别是引用[2]和引用[4],它们提到了Spring BootRedisTemplate的默认序列化问题以及自定义序列化的方法。 用户需求:在Spring Boot中实现Redis数据的自定义序列化。 步骤: 1. 添加依赖(引用[5]提供了依赖配置) 2. 自定义RedisTemplate,主要设置序列化方式(引用[2]提到默认的RedisTemplate没有设置合适的序列化方式,引用[4]提到了使用JSON序列化) 3. 配置序列化器,例如使用Jackson2JsonRedisSerializer来序列化value为JSON字符串(引用[4]) 具体实现: 我们可以创建一个配置类,在其中定义RedisTemplate的Bean,并设置key和value的序列化方式。 注意:引用[3]中使用了RedisTemplate<String, String>,但用户需要自定义序列化,所以我们将使用自定义的序列化器。 示例配置类: ```java import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; @Configuration public class RedisConfig { @Bean public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) { RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(redisConnectionFactory); // 使用Jackson2JsonRedisSerializer来序列化反序列化redis的value值(默认使用JDK的序列化方式) Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class); // 解决查询缓存转换异常的问题 // 这里可以配置ObjectMapper,比如设置日期格式等,根据需求来 // ObjectMapper om = new ObjectMapper(); // om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); // om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); // jackson2JsonRedisSerializer.setObjectMapper(om); // 设置key和value的序列化方式 redisTemplate.setKeySerializer(new StringRedisSerializer()); // key采用String的序列化方式 redisTemplate.setValueSerializer(jackson2JsonRedisSerializer); // value序列化方式采用jackson redisTemplate.setHashKeySerializer(new StringRedisSerializer()); // hash的key也采用String的序列化方式 redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer); // hash的value采用jackson redisTemplate.afterPropertiesSet(); return redisTemplate; } } ``` 说明: - 我们使用StringRedisSerializer来序列化key,这样key就会以字符串形式存储,便于阅读。 - 使用Jackson2JsonRedisSerializer来序列化value,这样存储的值将是JSON格式。 - 如果需要序列化的对象比较复杂,可能需要配置ObjectMapper(如注释部分),以避免转换异常。 另外,引用[4]中提到了一种在RedisSerializationContext中使用JSON序列化的方式,但上面的配置是针对RedisTemplate的,这是两种同的方式(RedisTemplate和ReactiveRedisTemplate或RedisCacheManager等)。这里我们按照用户需求,针对RedisTemplate进行配置。 测试: 可以像引用[3]中那样注入RedisTemplate进行测试,但注意类型要匹配,我们这里定义的是RedisTemplate<String, Object>。 测试代码示例: ```java @SpringBootTest public class RedisTest { @Autowired private RedisTemplate<String, Object> redisTemplate; @Test public void test() { User user = new User("张三", 25); redisTemplate.opsForValue().set("user:1", user); User user1 = (User) redisTemplate.opsForValue().get("user:1"); System.out.println(user1); } } ``` 注意:User类需要实现Serializable接口吗? 使用Jackson2JsonRedisSerializer需要实现Serializable接口,因为它使用的是JSON序列化,而Java原生序列化。 但是,如果使用默认的JdkSerializationRedisSerializer,则对象必须实现Serializable接口(引用[2]提到过)。 因此,使用我们自定义的JSON序列化方式,对象需要实现Serializable接口。 相关问题: 根据用户的问题,生成一些相关问题,以帮助用户深入理解。 §§相关问题§§ 1. 如何在Spring Boot中配置RedisTemplate使用同的序列化方式(如JSON、String等)? 2. 除了Jackson2JsonRedisSerializer,还有哪些常用的Redis序列化器? 3. 如何为Redis的hash类型数据单独配置序列化方式? 4. 自定义序列化后,如何确保已经存储在Redis中的数据兼容? 5. 在Spring Boot中,除了自定义RedisTemplate,还有哪些方式可以实现自定义序列化(例如通过RedisCacheManager)?</think>### Spring Boot Redis 自定义序列化方法 在 Spring Boot 中实现 Redis 数据的自定义序列化,可通过配置自定义的 `RedisTemplate` 实现。以下是详细步骤: #### 1. 添加依赖 确保 `pom.xml` 包含 Redis 和 JSON 序列化依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> </dependency> ``` #### 2. 创建配置类 定义 `RedisConfig` 配置类,自定义序列化方式(以 JSON 为例): ```java import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; @Configuration public class RedisConfig { @Bean public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) { RedisTemplate<String, Object> template = new RedisTemplate<>(); template.setConnectionFactory(factory); // Key 序列化为 String template.setKeySerializer(new StringRedisSerializer()); // Value 序列化为 JSON Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class); template.setValueSerializer(serializer); // Hash Key/Value 序列化 template.setHashKeySerializer(new StringRedisSerializer()); template.setHashValueSerializer(serializer); template.afterPropertiesSet(); return template; } } ``` #### 3. 使用自定义序列化 注入 `RedisTemplate` 操作数据,对象无需实现 `Serializable`: ```java @Autowired private RedisTemplate<String, Object> redisTemplate; public void saveUser(User user) { // 自动序列化为 JSON redisTemplate.opsForValue().set("user:" + user.getId(), user); } public User getUser(String id) { // 自动反序列化为对象 return (User) redisTemplate.opsForValue().get("user:" + id); } ``` #### 关键配置说明 1. **序列化器选择**: - `StringRedisSerializer`:处理 String 类型的 key - `Jackson2JsonRedisSerializer`:将对象转为 JSON 存储[^4] 2. **优势**: - 避免默认 JDK 序列化的二进制数据(可读性差) - 支持跨语言数据交换 - 对象无需实现 `Serializable` 接口[^2] #### 测试验证 ```java @Test void testCustomSerialization() { User user = new User("张三", 25); redisTemplate.opsForValue().set("test:user", user); User cachedUser = (User) redisTemplate.opsForValue().get("test:user"); System.out.println(cachedUser.getName()); // 输出 "张三" } ``` > **注意**:如果使用 `@Cacheable` 注解,需额外配置 `RedisCacheManager` 的序列化方式,原理类似[^4]。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱生活,更爱技术

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值