redis set值乱码
时间: 2025-06-03 11:29:23 浏览: 19
### Redis Set 操作存储数据出现乱码的原因
当使用 `set` 命令向 Redis 中存入字符串类型的键值对时,如果未指定编码方式,则 Redis 默认以二进制形式保存这些数据。这可能导致在某些情况下读取或展示时遇到乱码现象[^1]。
对于 Java 应用程序而言,在 Spring Boot 或其他框架下利用 Jedis 客户端连接并操作 Redis 服务器的过程中,默认采用 JDK 的序列化机制来处理对象与字节数组之间的转换。这种做法虽然能够兼容多种复杂结构的对象持久化需求,但对于简单的 String 类型来说却显得过于冗余,并容易引发不必要的麻烦——比如上述提到的乱码问题[^2]。
### 解决方案
为了防止此类情况的发生,可以调整用于通信双方之间交换信息所使用的编解码器(即 Serializer)。具体措施是在配置文件中修改 RedisTemplate 实例的相关属性:
#### 方法一:更改默认序列化器为 StringRedisSerializer
```yaml
spring:
redis:
template:
value-serializer-type: string
```
或者通过编程的方式设定:
```java
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(factory);
Jackson2JsonRedisSerializer<Object> jacksonSer = new Jackson2JsonRedisSerializer<>(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jacksonSer.setObjectMapper(om);
// 设置key和hashKey都采用StringRedisSerializer序列化方式
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(jacksonSer);
template.afterPropertiesSet();
return template;
}
```
此方法适用于希望所有基于该模板的操作均遵循相同规则的应用场景;而对于仅需针对特定业务逻辑做特殊处理的情形,则推荐下面的方法。
#### 方法二:自定义序列化工具类
创建一个新的工具类来进行手动控制序列化的流程,确保每次调用 set/get 接口前都将目标对象转化为 UTF8 编码下的纯文本格式再传递给底层驱动完成实际 I/O 操作。
```java
import org.springframework.data.redis.serializer.StringRedisSerializer;
// ... other imports ...
@Component
public class CustomRedisUtil {
private final RedisTemplate<String, String> redisTemplate;
@Autowired
public CustomRedisUtil(@Qualifier("stringRedisTemplate") RedisTemplate<String, String> redisTemplate){
this.redisTemplate=redisTemplate;
// Ensure the serializer is correctly configured.
if (!(this.redisTemplate.getKeySerializer() instanceof StringRedisSerializer)) {
throw new IllegalStateException("Expected a StringRedisSerializer as key serializer");
}
if (!(this.redisTemplate.getValueSerializer() instanceof StringRedisSerializer)) {
throw new IllegalStateException("Expected a StringRedisSerializer as value serializer");
}
}
/**
* Sets a given key-value pair into Redis with proper encoding.
*/
public void safeSet(String key, String value){
try{
byte[] encodedValue=value.getBytes("UTF-8");
redisTemplate.opsForValue().set(key,new String(encodedValue));
}catch(Exception e){
log.error("Failed to safely store data in Redis",e);
}
}
/**
* Retrieves and decodes a stored value from Redis by its key.
*/
public Optional<String> safeGet(String key){
try{
String rawValue=(String)this.redisTemplate.opsForValue().get(key);
if(rawValue!=null && !rawValue.isEmpty()){
return Optional.ofNullable(new String(rawValue.getBytes(), "UTF-8"));
}
}catch(Exception e){
log.warn("Error occurred while fetching or decoding data.",e);
}
return Optional.empty();
}
}
```
这种方法允许开发者更加灵活地管理不同类型的数据流以及它们对应的编码/解码过程,从而有效规避因不当设置而导致的一系列潜在风险。
阅读全文
相关推荐


















