摘要:是框架對(duì)的默認(rèn)集成,我們?cè)趯?shí)際項(xiàng)目中,也經(jīng)常使用它的去操作,一般來(lái)說(shuō)沒什么問題,但是細(xì)心一點(diǎn)的同學(xué)會(huì)發(fā)現(xiàn),經(jīng)過(guò)這種方法寫入的數(shù)據(jù)會(huì)出現(xiàn)亂碼問題問題復(fù)現(xiàn)項(xiàng)目依賴配置文件配置配置類注入設(shè)置數(shù)據(jù)存入的序列化方式實(shí)例化對(duì)象可以
org.springframework.data.redis是Spring框架對(duì)Redis的默認(rèn)集成,我們?cè)趯?shí)際項(xiàng)目中,也經(jīng)常使用它的RedisTemplate去操作Redis,一般來(lái)說(shuō)沒什么問題,但是細(xì)心一點(diǎn)的同學(xué)會(huì)發(fā)現(xiàn),經(jīng)過(guò)這種方法寫入redis的數(shù)據(jù)會(huì)出現(xiàn)亂碼問題問題復(fù)現(xiàn) 項(xiàng)目依賴
Redis配置org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-starter-data-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測(cè)試代碼functionDomainRedisTemplate() { RedisTemplate redisTemplate = new RedisTemplate<>(); initDomainRedisTemplate(redisTemplate, redisConnectionFactory); return redisTemplate; } /** * 設(shè)置數(shù)據(jù)存入 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); } /** * 實(shí)例化 HashOperations 對(duì)象,可以使用 Hash 類型操作 * * @param redisTemplate * @return */ @Bean public HashOperations hashOperations(RedisTemplate redisTemplate) { return redisTemplate.opsForHash(); } /** * 實(shí)例化 ValueOperations 對(duì)象,可以使用 String 操作 * * @param redisTemplate * @return */ @Bean public ValueOperations valueOperations(RedisTemplate redisTemplate) { return redisTemplate.opsForValue(); } /** * 實(shí)例化 ListOperations 對(duì)象,可以使用 List 操作 * * @param redisTemplate * @return */ @Bean public ListOperations listOperations(RedisTemplate redisTemplate) { return redisTemplate.opsForList(); } /** * 實(shí)例化 SetOperations 對(duì)象,可以使用 Set 操作 * * @param redisTemplate * @return */ @Bean public SetOperations setOperations(RedisTemplate redisTemplate) { return redisTemplate.opsForSet(); } /** * 實(shí)例化 ZSetOperations 對(duì)象,可以使用 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 ListOperationslistOperations; @Test public void leftPushTest () { List list = new ArrayList<>(); list.add("hello world"); listOperations.leftPush("listKey", list); } }
運(yùn)行上述測(cè)試代碼后,我們會(huì)在redis中插入一組list類型的數(shù)據(jù),其key為listKey,value為只有一個(gè)元素的list對(duì)象
接下來(lái)我們通過(guò)redis-cli去獲取listKey這個(gè)值,可以看到亂碼的出現(xiàn):
127.0.0.1:6379> LRANGE listKey 0 10 1) "xacxedx00x05srx00x13java.util.ArrayListxx81xd2x1dx99xc7ax9dx03x00x01Ix00x04sizexpx00x00x00x01wx04x00x00x00x01tx00x0bhello worldx"
當(dāng)然,這對(duì)于我們項(xiàng)目的實(shí)際使用沒有什么影響,在程序中再次獲取listKey也不會(huì)出現(xiàn)亂碼,只有通過(guò)redis-cli等工具直接取值的時(shí)候,才會(huì)出現(xiàn)亂碼
問題出現(xiàn)原因問題原因在于我們對(duì)Redis進(jìn)行配置的這一段代碼(事實(shí)上這也是redisTemplate的默認(rèn)配置代碼):
private void initDomainRedisTemplate(RedisTemplateredisTemplate, RedisConnectionFactory factory) { redisTemplate.setKeySerializer(new StringRedisSerializer()); redisTemplate.setHashKeySerializer(new StringRedisSerializer()); redisTemplate.setHashValueSerializer(new JdkSerializationRedisSerializer()); redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer()); redisTemplate.setConnectionFactory(factory); }
在這里,redisTemplate對(duì)HashValue和Value的序列化類采用的是JDK默認(rèn)的序列化策略,而不是String類型的序列化策略,所以我們?cè)趓edis-cli中看到的value會(huì)因?yàn)樾蛄谢呗缘膯栴},出現(xiàn)亂碼
解決辦法將JDK默認(rèn)的序列化策略更換為String類型的序列化策略
redisTemplate.setHashValueSerializer(new StringRedisSerializer()); redisTemplate.setValueSerializer(new StringRedisSerializer());
但是這樣做的話,我們?cè)谶M(jìn)行存儲(chǔ)的時(shí)候,也只能存儲(chǔ)String類型的數(shù)據(jù),所以測(cè)試代碼要進(jìn)行如下修改
@Test public void leftPushTest () { Listlist = new ArrayList<>(); list.add("hello world2"); listOperations.leftPush("listKey", list.toString()); }
再一次去redis-cli中取值,得到如下結(jié)果:
127.0.0.1:6379> LRANGE listKey 0 10 1) "[hello world2]" 2) "xacxedx00x05srx00x13java.util.ArrayListxx81xd2x1dx99xc7ax9dx03x00x01Ix00x04sizexpx00x00x00x01wx04x00x00x00x01tx00x0bhello worldx"
可以發(fā)現(xiàn)亂碼問題已經(jīng)解決
總結(jié)不建議更換redisTemplate默認(rèn)的序列化策略,有亂碼就讓它亂著吧,反正知道正確的解碼策略就不會(huì)影響程序的正常運(yùn)行(不過(guò)通過(guò)php等其他語(yǔ)言去獲取redis的值貌似不太好解決)
如果一定要更換策略,那么前往要注意,存儲(chǔ)數(shù)據(jù)的類型要根據(jù)所選擇的序列化策略去進(jìn)行切換
項(xiàng)目案例源代碼:github/booklet-redis
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/75877.html
摘要:爬蟲數(shù)據(jù)寫入文件中文亂碼,用在中打開文件沒有問題,但是用打開卻出現(xiàn)了問題,以下為解決方法。 python爬蟲數(shù)據(jù)寫入csv文件中文亂碼,用’utf-8‘在pycharm中打開文件沒有問題,但是用excel打開卻出現(xiàn)了問題,以下為解決方法。 (最近在練習(xí)爬蟲,這個(gè)博文是對(duì)自己學(xué)習(xí)的記錄和分享,...
閱讀 2157·2021-11-11 16:55
閱讀 1501·2021-09-28 09:36
閱讀 1099·2019-08-29 15:21
閱讀 1650·2019-08-29 14:10
閱讀 2837·2019-08-29 14:08
閱讀 1690·2019-08-29 12:31
閱讀 3312·2019-08-29 12:31
閱讀 1089·2019-08-26 16:47