org.springframework.data.redis是Spring框架对Redis的默认集成,我们在实际项目中,也经常使用它的RedisTemplate去操作Redis,一般来说没什么问题,但是细心一点的同学会发现,经过这种方法写入redis的数据会出现乱码问题

问题复现

项目依赖

org.springframework.boot

spring-boot-starter-web

org.springframework.boot

spring-boot-starter-test

test

org.springframework.boot

spring-boot-starter-data-redis

Redis配置

yaml文件配置

spring:

application:

name: booklet-redis

redis:

host: 127.0.0.1

port: 6379

password: adminadmin

timeout: 5000ms

Redis配置类

package com.liumapp.booklet.redis.config;

import org.springframework.beans.factory.annotation.Autowired;

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.*;

import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;

import org.springframework.data.redis.serializer.StringRedisSerializer;

@Configuration

public class RedisConfig {

/**

* 注入 RedisConnectionFactory

*/

@Autowired

RedisConnectionFactory redisConnectionFactory;

@Bean

public RedisTemplate functionDomainRedisTemplate() {

RedisTemplate redisTemplate = new RedisTemplate<>();

initDomainRedisTemplate(redisTemplate, redisConnectionFactory);

return redisTemplate;

}

/**

* 设置数据存入 redis 的序列化方式

*

* @param redisTemplate

* @param factory

*/

private void initDomainRedisTemplate(RedisTemplate redisTemplate, RedisConnectionFactory factory) {

redisTemplate.setKeySerializer(new StringRedisSerializer());

redisTemplate.setHashKeySerializer(new StringRedisSerializer());

redisTemplate.setHashValueSerializer(new JdkSerializationRedisSerializer());

redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());

redisTemplate.setConnectionFactory(factory);

}

/**

* 实例化 HashOperations 对象,可以使用 Hash 类型操作

*

* @param redisTemplate

* @return

*/

@Bean

public HashOperations hashOperations(RedisTemplate redisTemplate) {

return redisTemplate.opsForHash();

}

/**

* 实例化 ValueOperations 对象,可以使用 String 操作

*

* @param redisTemplate

* @return

*/

@Bean

public ValueOperations valueOperations(RedisTemplate redisTemplate) {

return redisTemplate.opsForValue();

}

/**

* 实例化 ListOperations 对象,可以使用 List 操作

*

* @param redisTemplate

* @return

*/

@Bean

public ListOperations listOperations(RedisTemplate redisTemplate) {

return redisTemplate.opsForList();

}

/**

* 实例化 SetOperations 对象,可以使用 Set 操作

*

* @param redisTemplate

* @return

*/

@Bean

public SetOperations setOperations(RedisTemplate redisTemplate) {

return redisTemplate.opsForSet();

}

/**

* 实例化 ZSetOperations 对象,可以使用 ZSet 操作

*

* @param redisTemplate

* @return

*/

@Bean

public ZSetOperations zSetOperations(RedisTemplate redisTemplate) {

return redisTemplate.opsForZSet();

}

}

测试代码

package com.liumapp.booklet.redis;

import org.junit.Test;

import org.junit.runner.RunWith;

import org.springframework.boot.test.context.SpringBootTest;

import org.springframework.data.redis.core.ListOperations;

import org.springframework.test.context.junit4.SpringRunner;

import javax.annotation.Resource;

import java.util.ArrayList;

import java.util.List;

@SpringBootTest(classes = BookletRedisMain.class)

@RunWith(SpringRunner.class)

public class BookletRedisMainTest {

@Resource

private ListOperations listOperations;

@Test

public void leftPushTest () {

List list = new ArrayList<>();

list.add("hello world");

listOperations.leftPush("listKey", list);

}

}

运行上述测试代码后,我们会在redis中插入一组list类型的数据,其key为listKey,value为只有一个元素的list对象

接下来我们通过redis-cli去获取listKey这个值,可以看到乱码的出现:

127.0.0.1:6379> LRANGE listKey 0 10

1) "\xac\xed\x00\x05sr\x00\x13java.util.ArrayListx\x81\xd2\x1d\x99\xc7a\x9d\x03\x00\x01I\x00\x04sizexp\x00\x00\x00\x01w\x04\x00\x00\x00\x01t\x00\x0bhello worldx"

当然,这对于我们项目的实际使用没有什么影响,在程序中再次获取listKey也不会出现乱码,只有通过redis-cli等工具直接取值的时候,才会出现乱码

问题出现原因

问题原因在于我们对Redis进行配置的这一段代码(事实上这也是redisTemplate的默认配置代码):

private void initDomainRedisTemplate(RedisTemplate redisTemplate, RedisConnectionFactory factory) {

redisTemplate.setKeySerializer(new StringRedisSerializer());

redisTemplate.setHashKeySerializer(new StringRedisSerializer());

redisTemplate.setHashValueSerializer(new JdkSerializationRedisSerializer());

redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());

redisTemplate.setConnectionFactory(factory);

}

在这里,redisTemplate对HashValue和Value的序列化类采用的是JDK默认的序列化策略,而不是String类型的序列化策略,所以我们在redis-cli中看到的value会因为序列化策略的问题,出现乱码

解决办法

将JDK默认的序列化策略更换为String类型的序列化策略

redisTemplate.setHashValueSerializer(new StringRedisSerializer());

redisTemplate.setValueSerializer(new StringRedisSerializer());

但是这样做的话,我们在进行存储的时候,也只能存储String类型的数据,所以测试代码要进行如下修改

@Test

public void leftPushTest () {

List list = new ArrayList<>();

list.add("hello world2");

listOperations.leftPush("listKey", list.toString());

}

再一次去redis-cli中取值,得到如下结果:

127.0.0.1:6379> LRANGE listKey 0 10

1) "[hello world2]"

2) "\xac\xed\x00\x05sr\x00\x13java.util.ArrayListx\x81\xd2\x1d\x99\xc7a\x9d\x03\x00\x01I\x00\x04sizexp\x00\x00\x00\x01w\x04\x00\x00\x00\x01t\x00\x0bhello worldx"

可以发现乱码问题已经解决

总结

不建议更换redisTemplate默认的序列化策略,有乱码就让它乱着吧,反正知道正确的解码策略就不会影响程序的正常运行(不过通过php等其他语言去获取redis的值貌似不太好解决)

如果一定要更换策略,那么前往要注意,存储数据的类型要根据所选择的序列化策略去进行切换

redis 值字符串前面部分乱码_Spring-RedisTemplate写入数据乱码问题的复现与解决相关推荐

  1. (已解决)RedisTemplate写入数据 \xAC\xED\x00\x05t\x00 序列化问题

    先看现象: Spring使用RedisTemplate进行数据缓存的时候,发现缓存的数据有序列化问题 话不多说,上图 不仅仅是key出现这种序列化问题,而且value也会出现这种情况 先把解决方案放着 ...

  2. redis 值字符串前面部分乱码_解决spring boot redis序列化key-value乱码

    最近使用spring-data-redis RedisTemplate 操作redis时发现存储在redis中的key不是设置的string值, 前面还多出了许多类似\xac\xed\x00\x05t ...

  3. redis 值字符串前面部分乱码_使用redis添加的数据,value有乱码前缀

    Cache cache = Redis.(); String value = "android"+queue.size(); String key = "123" ...

  4. redis 值字符串前面部分乱码_StringBoot 整合Redis解决存储乱码(通过StringRedisSerializer来进行序列化)...

    org.springframework.boot spring-boot-starter-redis 1.4.7.RELEASE 注意: spring-boot-starter-data-redis ...

  5. redis 值字符串前面部分乱码_redis key乱码

    {"moduleinfo":{"card_count":[{"count_phone":1,"count":1}],&q ...

  6. linux mariadb 乱码,MariaDB插入中文数据乱码解决过程

    基本情况: MariaDB安装方式:yum 乱码解决过程: 1.查看当前数据库编码(登录数据库后) # show variables like 'character%'; (上图为已经配置成功) 2. ...

  7. linux版本kettle 中文乱码,kettle工具同步数据乱码-Linux下乱码问题二

    json校验 直接百度:json在线解析  或  json.cnhttp://json.cn/ json格式校验的.这个更加简洁些. SQL语句构建器类 问题 Java程序员面对的最痛苦的事情之一就是 ...

  8. mysql写入数据乱码问题的解决

    mysql默认编码为latin. 我的mysql版本为5.6.安装路径下没有my.ini,但是有my-default.ini.其实mysql没有配置文件也是可以启动的,但是为了设置编码,需要将my-d ...

  9. RedisTemplate写入Redis数据出现无意义乱码前缀\xac\xed\x00\x05

    背景 项目使用Spring的RedisTemplate进行Redis数据存取操作,实际应用中发现Redis中key和value会出现"无意义"乱码前缀\xac\xed\x00\x0 ...

最新文章

  1. 团队文化之表扬和批评
  2. Android 之UID and PID
  3. 红帽linux cd命令,redhat linux 文件操作
  4. Spring security/Shiro ---登陆成功后返回登陆前界面<页面重定向>
  5. 人工智能时代,学好数学有什么用?
  6. 【UOJ139】【UER #4】被删除的黑白树
  7. SpringCloud微框架系列整体模块梳理
  8. Linux设备驱动--块设备(一)之概念和框架(转)
  9. 基于line2d算法的模板匹配
  10. 窗口启动特效,使用win32 api
  11. 瑞信:区块链技术还在半山腰 2025年才能真正成熟
  12. linux下oracle完全卸载,linux环境下卸载oracle 11g
  13. Echarts地图高亮循环数据展示
  14. 【060】助力一箭四星,翼辉系统再续辉煌
  15. Cross-speaker Style Transfer with Prosody Bottleneck in Neural Speech Synthesis
  16. Windows Defender保护历史记录清空方法
  17. JavaWeb_CSS(14)_文字处理_字体和字号
  18. qt调用simsimi api实现小黄鸡
  19. vue无法加载文件C:\Users\Administrator\AppData\Roaming\npm\vue.ps1因为在此系统上禁止运行脚本……解决办法
  20. 明年9月,南京大学苏州校区将正式招生!

热门文章

  1. #CSP 201709-1 打酱油
  2. ##CSP 201512-3 画图(C语言)
  3. 小技巧 ----- 位运算的一些结论与应用
  4. leetcode958. Check Completeness of a Binary Tree
  5. UML--行为图(状态图、活动图)
  6. 【编程珠玑】第九章 代码调优
  7. 简单干净的C#方法设计案例:SFCUI.AjaxValue()之二
  8. 敏捷开发一千零一问系列之九:总体架构什么时机进行?(上)
  9. 从一次线上故障思考Java问题定位思路
  10. Tensorflow训练神经网络