實例講解Springboot以Template方式整合Redis及序列化問題

来源:https://www.cnblogs.com/larrydpk/archive/2020/04/24/12770541.html
-Advertisement-
Play Games

1 簡介 之前講過如何通過 安裝 ,也講了 以`Repository Redis`,建議閱讀後再看本文效果更佳: (1) "Docker安裝Redis並介紹漂亮的可視化客戶端進行操作" (2) "實例講解Springboot以Repository方式整合Redis" 本文將通過實例講解 以`Temp ...


1 簡介

之前講過如何通過Docker安裝Redis,也講了SpringbootRepository方式整合Redis,建議閱讀後再看本文效果更佳:

(1) Docker安裝Redis並介紹漂亮的可視化客戶端進行操作

(2) 實例講解Springboot以Repository方式整合Redis

本文將通過實例講解SpringbootTemplate方式整合Redis,並遇到一些序列化的問題。代碼結構如下:

2 整合過程

與文章《實例講解Springboot以Repository方式整合Redis》相同的代碼不再列出來,文末將提供代碼下載方式。

2.1 自動配置類

把相關依賴引入到項目中後,Springboot就自動幫我們生成了Template類,分別是RedisTemplateStringRedisTemplate。看一下自動配置類能看出這兩個類都已經創建到Spring容器里了。

public class RedisAutoConfiguration {
    public RedisAutoConfiguration() {
    }

    @Bean
    @ConditionalOnMissingBean( name = {"redisTemplate"} )
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
        RedisTemplate<Object, Object> template = new RedisTemplate();
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }

    @Bean
    @ConditionalOnMissingBean
    public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
        StringRedisTemplate template = new StringRedisTemplate();
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }
}

實際上StringRedisTemplateRedisTemplate的子類,對於String類型,更推薦使用前者,它的類型只能是String的,會有類型檢查上的安全;而RedisTemplate可以操作任何類型。

2.2 實現數據訪問層

本文通過RedisTemplateRedis進行操作,所以我們需要將它註入進來。代碼如下:

package com.pkslow.springbootredistemplate.dal;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Repository;

@Repository
public class UserDAL {
    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;

    public void setValue(Object key, Object value) {
        redisTemplate.opsForValue().set(key, value);
    }

    public Object getValue(Object key) {
        return redisTemplate.opsForValue().get(key);
    }
}

RedisTemplate提供了豐富的方法,具體可以參考官方文檔,本次用到的及類似的方法有:

  • opsForHash(): 返回對於Hash的操作類;
  • opsForList(): 返回對於列表List的操作類;
  • opsForSet(): 返回對於Set的操作類;
  • opsForValue(): 返回對於字元串String的操作類;
  • opsForZSet(): 返回對於ZSet的操作類。

2.3 實現Controller

我們需要把功能通過Web的方式暴露出去,實現以下Contrller

package com.pkslow.springbootredistemplate.controller;

import com.pkslow.springbootredistemplate.dal.UserDAL;
import com.pkslow.springbootredistemplate.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/userTemplate")
public class UserTemplateController {

    @Autowired
    private final UserDAL userDAL;

    public UserTemplateController(UserDAL userDAL) {
        this.userDAL = userDAL;
    }

    @GetMapping("/{userId}")
    public User getByUserId(@PathVariable String userId) {
        return (User)userDAL.getValue(userId);
    }

    @PostMapping("/{userId}")
    public User addNewUser(@PathVariable String userId,
                           @RequestBody User user) {
        user.setUserId(userId);
        userDAL.setValue(userId, user);
        return user;
    }

}

只提供兩個介面,分別是設值和取值。

2.4 通過Postman測試

(1)存入對象

(2)讀取對象

能寫能讀,功能實現,完美!Perfect!收工!

3 序列化問題

程式功能正常運行一段時間後,運維殺來了:“這是什麼東西?我怎麼看得懂?我要怎麼查看數據?”

3.1 定位問題

不得不重新打開項目代碼,Debug一下看看哪出了問題。既然用Postman測試能正常顯示,而資料庫顯示不對,說明是寫入資料庫時做了轉換。查看RedisTemplate就行了,畢竟活是他乾的(先瘋狂甩鍋)。

Deubg

看它的序列化類用的是預設的JdkSerializationRedisSerializer,所以序列化後的數據我們看不懂。

3.2 問題修複

甩鍋完後,還是要修複問題的,畢竟代碼是自己寫的。關鍵就是替換掉RedisTemplate所使用的序列化類就行了,這有兩個方案可選:

(1)自定義一個新的RedisTemplate以覆蓋舊的,在定義的時候指定序列化類。大致代碼如下:

@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
  Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(Object.class);
  ObjectMapper om = new ObjectMapper();
  om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
  om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
  jackson2JsonRedisSerializer.setObjectMapper(om);

  RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
  template.setConnectionFactory(redisConnectionFactory);
  template.setKeySerializer(jackson2JsonRedisSerializer);
  template.setValueSerializer(jackson2JsonRedisSerializer);
  template.setHashKeySerializer(jackson2JsonRedisSerializer);
  template.setHashValueSerializer(jackson2JsonRedisSerializer);
  template.afterPropertiesSet();
  return template;
}

甚至還可以自定義RedisConnectionFactory,如下:

@Bean
JedisConnectionFactory jedisConnectionFactory() {
    JedisConnectionFactory jedisConFactory = new JedisConnectionFactory();
    jedisConFactory.setHostName("localhost");
    jedisConFactory.setPort(6379);
    return jedisConFactory;
}

(2)使用原有的RedisTemplate,在使用前替換掉序列化類

引用的類的代碼如下,init方法作為初始化方法:

public class UserDAL {
    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;

    public void init() {
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<>(Object.class));

    }

    public void setValue(Object key, Object value) {
        redisTemplate.opsForValue().set(key, value);
    }

    public Object getValue(Object key) {
        return redisTemplate.opsForValue().get(key);
    }
}

然後在創建UserDAL時,代碼如下:

@Bean(initMethod = "init")
public UserDAL userDAL() {
  return new UserDAL();
}

重新提交代碼、重新測試、重新發佈,結果可以了:

4 總結

本文詳細代碼可在南瓜慢說公眾號回覆<SpringbootRedisTemplate>獲取。


歡迎訪問南瓜慢說 www.pkslow.com獲取更多精彩文章!

歡迎關註微信公眾號<南瓜慢說>,將持續為你更新...

多讀書,多分享;多寫作,多整理。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1、創建Hibernate配置文件(hibernate.cfg.xml) <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configura ...
  • 1、查看你的Eclipse的版本:Help | About Eclipse Version: 2018-12 (4.10.0) 2、HibernateTools的下載地址為:http://www.jboss.org/tools/download/ !!!註意Eclipse版本號 Version: 2 ...
  • C++基礎 學習筆記六:複合類型之數組 什麼是數組 數組是有序的元素序列,是用於儲存多個相同類型數據的集合。 數組的定義 1. 聲明公式(一維) 1. 靜態數組 2. 動態數組 2. 關於數組的名詞解釋 1. 數組名 將有包含有限個類型相同的變數的集合命名,那麼這個集合的名稱為數組名。 2. 元素 ...
  • intellij idea中文資料網上比較少,對於eclipse的項目如何導入intellij idea也沒有完整的說明,本人在這裡整理下,方便更多人加入到intellij idea的陣容里。 直接上乾貨! 一、導入Eclipse項目至idea File – New – Module from Ex ...
  • 背景 保證kafka高吞吐量的另外一大利器就是消息壓縮。就像上圖中的壓縮餅干。 壓縮即空間換時間,通過空間的壓縮帶來速度的提升,即通過少量的cpu消耗來減少磁碟和網路傳輸的io。 消息壓縮模型 消息格式V1 kafka不會直接操作單條消息,而是直接操作一個消息集合。 消息格式V2: 1, 抽取了消息 ...
  • 官網文檔地址: "django admin和manage.py" 金句: 所有的天賦,都來自於你對你喜歡的某種事物的模仿與學習,否則你就不會有這種天賦。 開篇話: 我們在Django開發過程中,命令行執行最多的應該就是 ,今天聊聊manage.py這個命令。 記錄要點: 1. 和`manage.py ...
  • 最近總是做到有關博弈之類的題目,突然想認真的瞭解一下,現在將我的瞭解總結如下,希望對看到的人有所幫助。同時也請多多支持哈~~ 巴什博弈是眾多博弈種類中眾多的一種,同時也是最簡單的一種。它的基本模型是只有一堆物品,數量為n,兩個人輪流從這堆物品中拿走x(1<=x<=m)個,拿走最後一個的人獲勝。 這裡 ...
  • 1. Web基本概念 1. 1軟體架構 C/S:客戶端/服務端 B/S:瀏覽器/服務端 1. 2資源分類 靜態資源:所有用戶訪問的結果都是一樣的,稱為靜態資源,靜態資源可以被瀏覽器直接解析 如:html,css,JavaScript 動態資源:每個用戶訪問相同資源後,得到的結果可能不一樣,稱為動態資 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...