欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SpringBoot結(jié)合Redis實現(xiàn)序列化的方法詳解

 更新時間:2022年07月16日 08:58:57   作者:陜西顏值扛把子  
Spring提供了一個RedisTemplate來進行對Redis的操作,但是RedisTemplate默認配置的是使用Java本機序列化。如果要對對象操作,就不是那么的方便。所以本文為大家介紹了另一種SpringBoot結(jié)合Redis實現(xiàn)序列化的方法,需要的可以參考一下

前言

最近在學習Spring Boot結(jié)合Redis時看了一些網(wǎng)上的教程,發(fā)現(xiàn)這些教程要么比較老,要么不知道從哪抄得,運行起來有問題。這里分享一下我最新學到的寫法

默認情況下,Spring 為我們提供了一個 RedisTemplate 來進行對 Redis 的操作,但是 RedisTemplate 默認配置的是使用Java本機序列化。

這種序列化方式,對于操作字符串或數(shù)字來說,用起來還行,但是如果要對對象操作,就不是那么的方便了。

所以我們需要配置合適的序列化方式。在 Spring 官方的文檔中,官方也建議了我們使用其他的方式來進行序列化。比如JSON

https://docs.spring.io/spring-data/redis/docs/2.2.5.RELEASE/reference/html/#redis:serializer

配置類

配置 Jackson2JsonRedisSerializer 序列化策略

下面就開始自動配置類的書寫

我使用的是 Jackson2JsonRedisSerializer 來對對象進行序列化,所以首先需要一個方法,來配置 Jackson2JsonRedisSerializer 序列化策略

private Jackson2JsonRedisSerializer<Object> serializer() {
        // 使用Jackson2JsonRedisSerializer來序列化和反序列化redis的value值
        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
        ObjectMapper objectMapper = new ObjectMapper();

        // 指定要序列化的域,field,get和set,以及修飾符范圍,ANY是都有包括private和public
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);

        // 指定序列化輸入的類型,類必須是非final修飾的,final修飾的類,比如String,Integer等會跑出異常
        objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);

        jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
        return jackson2JsonRedisSerializer;
    }

這里要注意的是

objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);

這一句,這一句非常的重要,作用是序列化時將對象全類名一起保存下來

設置之后的序列化結(jié)果如下:

[
    "com.buguagaoshu.redis.model.User",
    {
        "name": "1",
        "age": "11",
        "message": "牛逼"
    }
]

不設置的話,序列化結(jié)果如下,將無法反序列化

{
        "name": "1",
        "age": "11",
        "message": "牛逼"
    }

一開始,我在網(wǎng)上搜了一下,發(fā)現(xiàn)大多數(shù)教程因為時間的原因,這一句用的是

objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);

但當我把這段代碼寫入的時候,發(fā)現(xiàn)Idea提示我

著是一個過時的方法,由于我當時并不知道這句話的意思,就把這段代碼注釋了,覺得可能沒什么用,但注釋后在向Redis里寫數(shù)據(jù)的時候,數(shù)據(jù)會變成

導致數(shù)據(jù)無法反序列化。

最后我查看了這個方法的源碼,找到了

通過注釋,我得到了這段代碼的最新寫法。

也明白了這段代碼的作用。

配置  RedisTemplate

@Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        // 用Jackson2JsonRedisSerializer來序列化和反序列化redis的value值
        redisTemplate.setValueSerializer(serializer());

        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        // 使用StringRedisSerializer來序列化和反序列化redis的key值
        redisTemplate.setKeySerializer(stringRedisSerializer);

        // hash的key也采用String的序列化方式
        redisTemplate.setHashKeySerializer(stringRedisSerializer);
        // hash的value序列化方式采用jackson
        redisTemplate.setHashValueSerializer(serializer());
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }

這里就沒有什么需要注意的了,按照自己的需求,來配置序列化的方式

配置緩存策略

@Bean
    public CacheManager cacheManager(RedisConnectionFactory factory) {
        RedisSerializer<String> redisSerializer = new StringRedisSerializer();
        // 配置序列化(解決亂碼的問題)
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
                // 緩存有效期
                .entryTtl(timeToLive)
                // 使用StringRedisSerializer來序列化和反序列化redis的key值
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
                // 使用Jackson2JsonRedisSerializer來序列化和反序列化redis的value值
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(serializer()))
                // 禁用空值
                .disableCachingNullValues();

        return RedisCacheManager.builder(factory)
                .cacheDefaults(config)
                .build();
    }

測試代碼

@SpringBootTest
public class RedisApplicationTests {
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;


    @Test
    void contextLoads() throws Exception {
        User user = new User();
        user.setName("15");
        user.setAge(20);
        user.setMessage("牛逼");
        redisTemplate.opsForValue().set(user.getName(), user);
        User getUser = (User) redisTemplate.opsForValue().get(user.getName());
        System.out.println(getUser);
        System.out.println(getUser.getMessage());
    }

}

再來查看Redis中的數(shù)據(jù)

數(shù)據(jù)正常,并且系統(tǒng)也能正常的反序列化了。

完整代碼

package com.buguagaoshu.redis.config;


import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.time.Duration;

/**
 * @author Pu Zhiwei {@literal puzhiweipuzhiwei@foxmail.com}
 * create          2020-03-17 21:08
 * 繼承 CachingConfigurerSupport,為了自定義生成 KEY 的策略??梢圆焕^承。
 */
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
    @Value("${spring.cache.redis.time-to-live}")
    private Duration timeToLive = Duration.ZERO;

    /**
     * 配置Jackson2JsonRedisSerializer序列化策略
     * */
    private Jackson2JsonRedisSerializer<Object> serializer() {
        // 使用Jackson2JsonRedisSerializer來序列化和反序列化redis的value值
        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
        ObjectMapper objectMapper = new ObjectMapper();

        // 指定要序列化的域,field,get和set,以及修飾符范圍,ANY是都有包括private和public
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);

        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);

        // 指定序列化輸入的類型,類必須是非final修飾的,final修飾的類,比如String,Integer等會跑出異常
        objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);

        jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
        return jackson2JsonRedisSerializer;
    }


    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        // 用Jackson2JsonRedisSerializer來序列化和反序列化redis的value值
        redisTemplate.setValueSerializer(serializer());

        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        // 使用StringRedisSerializer來序列化和反序列化redis的key值
        redisTemplate.setKeySerializer(stringRedisSerializer);

        // hash的key也采用String的序列化方式
        redisTemplate.setHashKeySerializer(stringRedisSerializer);
        // hash的value序列化方式采用jackson
        redisTemplate.setHashValueSerializer(serializer());
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }




    @Bean
    public CacheManager cacheManager(RedisConnectionFactory factory) {
        RedisSerializer<String> redisSerializer = new StringRedisSerializer();
        // 配置序列化(解決亂碼的問題)
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
                // 緩存有效期
                .entryTtl(timeToLive)
                // 使用StringRedisSerializer來序列化和反序列化redis的key值
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
                // 使用Jackson2JsonRedisSerializer來序列化和反序列化redis的value值
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(serializer()))
                // 禁用空值
                .disableCachingNullValues();

        return RedisCacheManager.builder(factory)
                .cacheDefaults(config)
                .build();
    }
}

以上就是SpringBoot結(jié)合Redis實現(xiàn)序列化的方法詳解的詳細內(nèi)容,更多關(guān)于SpringBoot Redis序列化的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Spring?Boot中使用Redis實戰(zhàn)案例

    Spring?Boot中使用Redis實戰(zhàn)案例

    redis作為一個高性能的內(nèi)存數(shù)據(jù)庫,如果不會用就太落伍了,之前在 node.js中用過 redis,本篇記錄如何將 redis 集成到 spring boot 中,下面這篇文章主要給大家介紹了關(guān)于Spring?Boot中使用Redis的相關(guān)資料,需要的朋友可以參考下
    2023-04-04
  • SpringMVC框架post提交數(shù)據(jù)庫出現(xiàn)亂碼解決方案

    SpringMVC框架post提交數(shù)據(jù)庫出現(xiàn)亂碼解決方案

    這篇文章主要介紹了SpringMVC框架post提交數(shù)據(jù)庫出現(xiàn)亂碼解決方案,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-09-09
  • java省市級聯(lián)下拉菜單實例代碼

    java省市級聯(lián)下拉菜單實例代碼

    這篇文章主要為大家詳細介紹了java省市級聯(lián)實例代碼,具有一定的參考價值,感興趣的朋友可以參考一下
    2016-05-05
  • java的SimpleDateFormat線程不安全的幾種解決方案

    java的SimpleDateFormat線程不安全的幾種解決方案

    但我們知道SimpleDateFormat是線程不安全的,處理時要特別小心,要加鎖或者不能定義為static,要在方法內(nèi)new出對象,再進行格式化,本文就介紹了幾種方法,感興趣的可以了解一下
    2021-08-08
  • 基于Java實現(xiàn)一個簡單的數(shù)據(jù)同步組件

    基于Java實現(xiàn)一個簡單的數(shù)據(jù)同步組件

    這篇文章主要為大家詳細介紹了如何基于Java實現(xiàn)一個簡單的數(shù)據(jù)同步組件,文中的示例代碼講解詳細,具有一定的借鑒價值,感興趣的小伙伴可以了解一下
    2023-06-06
  • IDEA生成patch和使用patch的方法實現(xiàn)

    IDEA生成patch和使用patch的方法實現(xiàn)

    比如你本地修復的 bug,需要把增量文件發(fā)給客戶,很多場景下大家都需要手工整理修改的文件,并整理好目錄,這個很麻煩,那有沒有簡單的技巧呢?本文主要介紹了IDEA生成patch和使用patch的方法實現(xiàn),感興趣的可以了解一下
    2023-08-08
  • Servlet實現(xiàn)多文件上傳功能

    Servlet實現(xiàn)多文件上傳功能

    這篇文章主要為大家詳細介紹了Servlet實現(xiàn)文件上傳功能,還可以實現(xiàn)Servlet多文件上傳功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-03-03
  • Java二分法查找_動力節(jié)點Java學院整理

    Java二分法查找_動力節(jié)點Java學院整理

    這篇文章主要介紹了Java二分法查找的相關(guān)資料,需要的朋友可以參考下
    2017-04-04
  • Spring中配置和讀取多個Properties文件的方式方法

    Spring中配置和讀取多個Properties文件的方式方法

    本篇文章主要介紹了Spring中配置和讀取多個Properties文件的方式方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下。
    2017-04-04
  • 解決IDEA中maven導入jar包一直報錯問題

    解決IDEA中maven導入jar包一直報錯問題

    這篇文章主要介紹了解決IDEA中maven導入jar包一直報錯問題,本文通過實例圖文的形式給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-04-04

最新評論