国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Spring-RedisTemplate寫入數據亂碼問題的復現與解決

李世贊 / 2599人閱讀

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

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) "xacxedx00x05srx00x13java.util.ArrayListxx81xd2x1dx99xc7ax9dx03x00x01Ix00x04sizexpx00x00x00x01wx04x00x00x00x01tx00x0bhello 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) "xacxedx00x05srx00x13java.util.ArrayListxx81xd2x1dx99xc7ax9dx03x00x01Ix00x04sizexpx00x00x00x01wx04x00x00x00x01tx00x0bhello worldx"

可以發現亂碼問題已經解決

總結

不建議更換redisTemplate默認的序列化策略,有亂碼就讓它亂著吧,反正知道正確的解碼策略就不會影響程序的正常運行(不過通過php等其他語言去獲取redis的值貌似不太好解決)

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

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

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/75877.html

相關文章

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

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

    zone 評論0 收藏0

發表評論

0條評論

李世贊

|高級講師

TA的文章

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