共80行
2026-07-14 15:55:18
LoginUserVO loginVO = new LoginUserVO(uid, token);
// 刷新缓存
String key = this.fixGetloginCacheKey(uid);
redisUtil.save(key, JSON.toJSONString(loginVO), 1, TimeUnit.DAYS);这是经典的 Redis 序列化问题。\xac\xed\x00\x05 是 Java 原生序列化的魔术数字,说明 RedisTemplate 使用的是 JDK 默认序列化器,而不是字符串序列化器。
让我确认下项目中是否有 Redis 的序列化配置。
找到原因了。项目中没有自定义 RedisTemplate 的序列化器配置,Spring Boot 默认使用的是 JdkSerializationRedisSerializer,这就是问题根源。
Key 变成 \xac\xed\x00\x05t\x00\x1cPARKING_INVOICE_USER_LOGIN_3:\xac\xed\x00\x05 是 Java 原生序列化的魔术数字(magic number),说明 key 也被 JDK 序列化了。正常情况下 key 应该用 StringRedisSerializer,直接存为可读字符串。
Value 变成 Binary 格式:同理,value 的序列化器也是 JdkSerializationRedisSerializer,所以 JSON.toJSONString(loginVO) 这个字符串被再次 JDK 序列化,存进去就变成了二进制。
在 infrastructure/config/ 下新建一个 Redis 配置类,自定义 RedisTemplate 的序列化器:
package com.dpb.tckp.infrastructure.config;
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;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(connectionFactory);
StringRedisSerializer stringSerializer = new StringRedisSerializer();
Jackson2JsonRedisSerializer<Object> jsonSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);
jsonSerializer.setObjectMapper(om);
template.setKeySerializer(stringSerializer);
template.setHashKeySerializer(stringSerializer);
template.setValueSerializer(jsonSerializer);
template.setHashValueSerializer(jsonSerializer);
template.afterPropertiesSet();
return template;
}
}配置后效果:
StringRedisSerializer,直接存为可读字符串 PARKING_INVOICE_USER_LOGIN_3Jackson2JsonRedisSerializer,存为 JSON 格式而非二进制⚠️ 注意:修改序列化方式后,Redis 中已有的旧数据(JDK 序列化格式的)将无法被正确反序列化,需要清除旧缓存或重新写入。