您好,登錄后才能下訂單哦!
本篇內容介紹了“Spring-RedisTemplate寫入數據出現亂碼怎么解決”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
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<String,Object> functionDomainRedisTemplate() { RedisTemplate<String,Object> redisTemplate = new RedisTemplate<>(); initDomainRedisTemplate(redisTemplate, redisConnectionFactory); return redisTemplate; } /** * 設置數據存入 redis 的序列化方式 * * @param redisTemplate * @param factory */ private void initDomainRedisTemplate(RedisTemplate<String,Object> 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<String, String, Object> hashOperations(RedisTemplate<String, Object> redisTemplate) { return redisTemplate.opsForHash(); } /** * 實例化 ValueOperations 對象,可以使用 String 操作 * * @param redisTemplate * @return */ @Bean public ValueOperations<String, Object> valueOperations(RedisTemplate<String, Object> redisTemplate) { return redisTemplate.opsForValue(); } /** * 實例化 ListOperations 對象,可以使用 List 操作 * * @param redisTemplate * @return */ @Bean public ListOperations<String, Object> listOperations(RedisTemplate<String, Object> redisTemplate) { return redisTemplate.opsForList(); } /** * 實例化 SetOperations 對象,可以使用 Set 操作 * * @param redisTemplate * @return */ @Bean public SetOperations<String, Object> setOperations(RedisTemplate<String, Object> redisTemplate) { return redisTemplate.opsForSet(); } /** * 實例化 ZSetOperations 對象,可以使用 ZSet 操作 * * @param redisTemplate * @return */ @Bean public ZSetOperations<String, Object> zSetOperations(RedisTemplate<String, Object> 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<String, Object> listOperations; @Test public void leftPushTest () { List<String> 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<String,Object> 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<String> 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的值貌似不太好解決)
“Spring-RedisTemplate寫入數據出現亂碼怎么解決”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。