成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Spring-RedisTemplate寫入數(shù)據(jù)亂碼問題的復現(xiàn)與解決

李世贊 / 2617人閱讀

摘要:是框架對的默認集成,我們在實際項目中,也經(jīng)常使用它的去操作,一般來說沒什么問題,但是細心一點的同學會發(fā)現(xiàn),經(jīng)過這種方法寫入的數(shù)據(jù)會出現(xiàn)亂碼問題問題復現(xiàn)項目依賴配置文件配置配置類注入設置數(shù)據(jù)存入的序列化方式實例化對象可以

org.springframework.data.redis是Spring框架對Redis的默認集成,我們在實際項目中,也經(jīng)常使用它的RedisTemplate去操作Redis,一般來說沒什么問題,但是細心一點的同學會發(fā)現(xiàn),經(jīng)過這種方法寫入redis的數(shù)據(jù)會出現(xiàn)亂碼問題
問題復現(xiàn) 項目依賴

  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;
    }

    /**
     * 設置數(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);
    }
    /**
     * 實例化 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類型的數(shù)據(jù),其key為listKey,value為只有一個元素的list對象

接下來我們通過redis-cli去獲取listKey這個值,可以看到亂碼的出現(xiàn):

127.0.0.1:6379> LRANGE listKey 0 10
1) "xacxedx00x05srx00x13java.util.ArrayListxx81xd2x1dx99xc7ax9dx03x00x01Ix00x04sizexpx00x00x00x01wx04x00x00x00x01tx00x0bhello worldx"

當然,這對于我們項目的實際使用沒有什么影響,在程序中再次獲取listKey也不會出現(xiàn)亂碼,只有通過redis-cli等工具直接取值的時候,才會出現(xiàn)亂碼

問題出現(xiàn)原因

問題原因在于我們對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會因為序列化策略的問題,出現(xiàn)亂碼

解決辦法

將JDK默認的序列化策略更換為String類型的序列化策略

redisTemplate.setHashValueSerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new StringRedisSerializer());

但是這樣做的話,我們在進行存儲的時候,也只能存儲String類型的數(shù)據(jù),所以測試代碼要進行如下修改

@Test
public void leftPushTest () {
    List list = 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默認的序列化策略,有亂碼就讓它亂著吧,反正知道正確的解碼策略就不會影響程序的正常運行(不過通過php等其他語言去獲取redis的值貌似不太好解決)

如果一定要更換策略,那么前往要注意,存儲數(shù)據(jù)的類型要根據(jù)所選擇的序列化策略去進行切換

項目案例源代碼:github/booklet-redis

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/75877.html

相關(guān)文章

  • Python 爬蟲數(shù)據(jù)寫入csv文件中文亂碼解決以及天眼查爬蟲數(shù)據(jù)寫入csv

    摘要:爬蟲數(shù)據(jù)寫入文件中文亂碼,用在中打開文件沒有問題,但是用打開卻出現(xiàn)了問題,以下為解決方法。 python爬蟲數(shù)據(jù)寫入csv文件中文亂碼,用’utf-8‘在pycharm中打開文件沒有問題,但是用excel打開卻出現(xiàn)了問題,以下為解決方法。 (最近在練習爬蟲,這個博文是對自己學習的記錄和分享,...

    zone 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<