Java中Redis存儲String類型會有亂碼的問題及解決方案
項目場景:
背景:在java中使用Redis存儲String類型的數據時,會出現亂碼。
問題描述:
例如:在java中創(chuàng)建RedisTemplate操作String類型的數據存儲時,會出現亂碼,如下代碼,
我寫了一條存儲key為name,值為虎哥的字符串。
然后獲取一下這個key為name的值,打印得到的值
package com.sxy.redis; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.redis.core.RedisTemplate; @SpringBootTest class SpringDataRedisDemoApplicationTests { @Autowired private RedisTemplate redisTemplate; @Test void contextLoads() { // 寫入一條String數據 redisTemplate.opsForValue().set("name", "虎哥"); // 獲取String數據 Object name = redisTemplate.opsForValue().get("name"); System.out.println("name=" + name); } }
我們可以看到出現了亂碼問題:這里不單單是值出現了亂碼,而且key也有亂碼問題
原因分析:
Redis的序列化分析:
因為SpringDataRedis的功能可以接收任何類型的對象,可以幫我們將java對象轉成Redis可處理的字節(jié),所以我們存進去的 name和虎哥 都被當成了java對象,而redisTemplate的底層,默認對這些對象得處理方式就是利用JDK的序列化工具,ObjectOutPutStream
進入redisTemplate我們發(fā)現了四個屬性的值都是對應的數據的序列化
這里我們發(fā)現上面四個屬性的值的,都是下面這個方法定義的默認的jdk的序列化器
通過斷點調試redisTemplate.opsForValue().set("name", "虎哥");我們可以發(fā)現,進入了JdkSerializationRedisSerializer的類中
最后進入了這里,可以看到有ObjectOutputStream來寫對象,這個流的作用就是把java對象轉換為字節(jié)進行writeObject進行寫入
所以我們看到的值就是這樣子的數據
缺點:
- 可讀性差
- 內存占用較大
解決方案:
我們可以通過修改RedisTemplate的序列化來實現數據亂碼問題。
RedisSerializer有一些實現類
這里會有兩個我們需要用到的
- StringRedisSerializer
如果我的key和hash可以是字符串的情況下就用它
- GenericJackson2JsonRedisSerializer
如果我的值是對象就用它
上代碼:
代碼如下,寫了一個配置類注冊Bean對象給spring容器管理
package com.sxy.redis.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.GenericJackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.RedisSerializer; @Configuration public class RedisConfig { @Bean public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory redisConnectionFactory){ // 創(chuàng)建RedisTemplate對象 RedisTemplate<String, Object> template = new RedisTemplate<>(); // 設置連接工廠 template.setConnectionFactory(redisConnectionFactory); // 創(chuàng)建JSON序列化工具 GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer(); // 設置key的序列化為 = String template.setKeySerializer(RedisSerializer.string()); template.setHashKeySerializer(RedisSerializer.string()); // 設置value的序列化為 = GenericJackson2JsonRedisSerializer template.setValueSerializer(genericJackson2JsonRedisSerializer); template.setHashValueSerializer(genericJackson2JsonRedisSerializer); // 返回 return template; } }
注意:如果這里運行的話會報錯為如下:
Caused by: java.lang.NoClassDefFoundError: com/fasterxml/jackson/core/JsonProcessingException
這是個明顯的錯誤,告訴我們用了如下這個JSON序列化類沒有引入jackson的依賴才報錯
GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer =
new GenericJackson2JsonRedisSerializer();
我們只需要添加如下依賴即可
<!-- Jackson依賴--> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> </dependency>
隨后我們嘗試對其進行寫入和讀取數據,發(fā)現key和value都是正常的顯示
總結:
直接在java中使用RedisTemplate模板進行寫入字符串數據時會出現,key和value都是亂碼問題,
我們修改了RedisTemplate默認的序列化器StringRedisSerializer即可解決此問題。
到此這篇關于Java中Redis存儲String類型會有亂碼的文章就介紹到這了,更多相關java redis存儲亂碼內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
java中創(chuàng)建寫入文件的6種方式詳解與源碼實例
這篇文章主要介紹了java中創(chuàng)建寫入文件的6種方式詳解與源碼實例,Files.newBufferedWriter(Java 8),Files.write(Java 7 推薦),PrintWriter,File.createNewFile,FileOutputStream.write(byte[] b) 管道流,需要的朋友可以參考下2022-12-12關于java.io.EOFException產生的原因以及解決方案
文章總結:EOFException異常通常發(fā)生在嘗試從空的ObjectInputStream對象中讀取數據時,解決方法是在finally語句中添加判斷,確保objectInputStream不為空后再進行關閉操作,在處理1.txt文件為空的情況時,捕獲EOFException可以避免程序終止,并且不會拋出空指針異常2025-01-01Mybatis #foreach中相同的變量名導致值覆蓋的問題解決
本文主要介紹了Mybatis #foreach中相同的變量名導致值覆蓋的問題解決,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-07-07使用spring security明文密碼校驗時報錯-BadCredentialsException:&nbs
小編遇到這樣一個問題在學習spring security時使用明文密碼進行登錄校驗時報錯"org.springframework.security.authentication.BadCredentialsException: Bad credentials,今天給大家分享問題原因及解決方案,感興趣的朋友一起看看吧2023-10-10詳解使用Spring快速創(chuàng)建web應用的兩種方式
這篇文章主要介紹了詳解使用Spring快速創(chuàng)建web應用的兩種方式,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-11-11