redis中序列化問題,value包含全路徑類名解析

1. 問題

redis中保存的key-value格式

value直接存入的是實體對象,值中包含全路徑類名,在使用Jackson2JsonRedisSerializerGenericJackson2JsonRedisSerializer解析器時報錯

報錯內容:

com.fasterxml.jackson.databind.exc.InvalidTypeIdException: 
Could not resolve type id 'entity.redis.IndexDetailDataDto' 
as a subtype of `java.lang.Object`: 
no such class found

value舉例:

["entity.redis.IndexDetailDataDto",{"slotId": "1001","date": ["java.util.Date",1698111839933],"status": null,"am": "自動"}
]

2. 解決辦法

  1. 項目中包含有entity.redis.IndexDetailDataDto的實體對象
  2. 使用FastJson2JsonRedisSerializer解析器轉化Json

建議使用第二種方法

3. springboot項目集成redis

a. 添加maven引用
<!--redis-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--spring2.X集成redis所需common-pool2-->
<dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId><version>2.6.0</version>
</dependency>
<!--fastjson-->
<dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.83</version>
</dependency>
b. 添加配置類
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.Feature;
import com.alibaba.fastjson.serializer.SerializerFeature;
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.RedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;
import org.springframework.data.redis.serializer.StringRedisSerializer;import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;// 標志為配置類
@Configuration
public class RedisConfig {// 把這個bean的name設置為redisTemplate,這樣我們才能全面接管redisTemplate!@Bean(name = "redisTemplate")public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory, RedisSerializer fastJson2JsonRedisSerializer) {RedisTemplate<String, Object> template = new RedisTemplate<>();template.setConnectionFactory(redisConnectionFactory);//key采用String序列化方式StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();template.setKeySerializer(stringRedisSerializer);template.setHashKeySerializer(stringRedisSerializer);//value采用fast-json序列化方式。template.setValueSerializer(fastJson2JsonRedisSerializer);template.setHashValueSerializer(fastJson2JsonRedisSerializer);template.afterPropertiesSet();return template;}@Beanpublic RedisSerializer fastJson2JsonRedisSerializer() {return new FastJson2JsonRedisSerializer<>(Object.class);}public static class FastJson2JsonRedisSerializer<T> implements RedisSerializer<T> {public static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8;private Class<T> clazz;public FastJson2JsonRedisSerializer(Class<T> clazz) {super();this.clazz = clazz;}@Overridepublic byte[] serialize(T t) throws SerializationException {if (t == null) {return new byte[0];}return JSON.toJSONString(t, SerializerFeature.WriteClassName).getBytes(DEFAULT_CHARSET);}@Overridepublic T deserialize(byte[] bytes) throws SerializationException {if (bytes == null || bytes.length <= 0) {return null;}String str = new String(bytes, DEFAULT_CHARSET);return JSON.parseObject(str, clazz, Feature.SupportAutoType);}}
c. 添加工具類
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;@Component
public final class RedisUtil {@Autowiredprivate RedisTemplate<String, Object> redisTemplate;// =============================common============================/*** 指定緩存失效時間* @param key  鍵* @param time 時間(秒)*/public boolean expire(String key, long time) {try {if (time > 0) {redisTemplate.expire(key, time, TimeUnit.SECONDS);}return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 根據key 獲取過期時間* @param key 鍵 不能為null* @return 時間(秒) 返回0代表為永久有效*/public long getExpire(String key) {return redisTemplate.getExpire(key, TimeUnit.SECONDS);}/*** 判斷key是否存在* @param key 鍵* @return true 存在 false不存在*/public boolean hasKey(String key) {try {return redisTemplate.hasKey(key);} catch (Exception e) {e.printStackTrace();return false;}}/*** 刪除緩存* @param key 可以傳一個值 或多個*/@SuppressWarnings("unchecked")public void del(String... key) {if (key != null && key.length > 0) {if (key.length == 1) {redisTemplate.delete(key[0]);} else {redisTemplate.delete((Collection<String>) CollectionUtils.arrayToList(key));}}}// ============================String=============================/*** 普通緩存獲取* @param key 鍵* @return 值*/public Object get(String key) {return key == null ? null : redisTemplate.opsForValue().get(key);}/*** 普通緩存放入* @param key   鍵* @param value 值* @return true成功 false失敗*/public boolean set(String key, Object value) {try {redisTemplate.opsForValue().set(key, value);return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 普通緩存放入并設置時間* @param key   鍵* @param value 值* @param time  時間(秒) time要大于0 如果time小于等于0 將設置無限期* @return true成功 false 失敗*/public boolean set(String key, Object value, long time) {try {if (time > 0) {redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);} else {set(key, value);}return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 遞增* @param key   鍵* @param delta 要增加幾(大于0)*/public long incr(String key, long delta) {if (delta < 0) {throw new RuntimeException("遞增因子必須大于0");}return redisTemplate.opsForValue().increment(key, delta);}/*** 遞減* @param key   鍵* @param delta 要減少幾(小于0)*/public long decr(String key, long delta) {if (delta < 0) {throw new RuntimeException("遞減因子必須大于0");}return redisTemplate.opsForValue().increment(key, -delta);}// ================================Map=================================/*** HashGet* @param key  鍵 不能為null* @param item 項 不能為null*/public Object hget(String key, String item) {return redisTemplate.opsForHash().get(key, item);}/*** 獲取hashKey對應的所有鍵值* @param key 鍵* @return 對應的多個鍵值*/public Map<Object, Object> hmget(String key) {return redisTemplate.opsForHash().entries(key);}/*** HashSet* @param key 鍵* @param map 對應多個鍵值*/public boolean hmset(String key, Map<String, Object> map) {try {redisTemplate.opsForHash().putAll(key, map);return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** HashSet 并設置時間* @param key  鍵* @param map  對應多個鍵值* @param time 時間(秒)* @return true成功 false失敗*/public boolean hmset(String key, Map<String, Object> map, long time) {try {redisTemplate.opsForHash().putAll(key, map);if (time > 0) {expire(key, time);}return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 向一張hash表中放入數據,如果不存在將創建** @param key   鍵* @param item  項* @param value 值* @return true 成功 false失敗*/public boolean hset(String key, String item, Object value) {try {redisTemplate.opsForHash().put(key, item, value);return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 向一張hash表中放入數據,如果不存在將創建** @param key   鍵* @param item  項* @param value 值* @param time  時間(秒) 注意:如果已存在的hash表有時間,這里將會替換原有的時間* @return true 成功 false失敗*/public boolean hset(String key, String item, Object value, long time) {try {redisTemplate.opsForHash().put(key, item, value);if (time > 0) {expire(key, time);}return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 刪除hash表中的值** @param key  鍵 不能為null* @param item 項 可以使多個 不能為null*/public void hdel(String key, Object... item) {redisTemplate.opsForHash().delete(key, item);}/*** 判斷hash表中是否有該項的值** @param key  鍵 不能為null* @param item 項 不能為null* @return true 存在 false不存在*/public boolean hHasKey(String key, String item) {return redisTemplate.opsForHash().hasKey(key, item);}/*** hash遞增 如果不存在,就會創建一個 并把新增后的值返回** @param key  鍵* @param item 項* @param by   要增加幾(大于0)*/public double hincr(String key, String item, double by) {return redisTemplate.opsForHash().increment(key, item, by);}/*** hash遞減** @param key  鍵* @param item 項* @param by   要減少記(小于0)*/public double hdecr(String key, String item, double by) {return redisTemplate.opsForHash().increment(key, item, -by);}// ============================set=============================/*** 根據key獲取Set中的所有值* @param key 鍵*/public Set<Object> sGet(String key) {try {return redisTemplate.opsForSet().members(key);} catch (Exception e) {e.printStackTrace();return null;}}/*** 根據value從一個set中查詢,是否存在** @param key   鍵* @param value 值* @return true 存在 false不存在*/public boolean sHasKey(String key, Object value) {try {return redisTemplate.opsForSet().isMember(key, value);} catch (Exception e) {e.printStackTrace();return false;}}/*** 將數據放入set緩存** @param key    鍵* @param values 值 可以是多個* @return 成功個數*/public long sSet(String key, Object... values) {try {return redisTemplate.opsForSet().add(key, values);} catch (Exception e) {e.printStackTrace();return 0;}}/*** 將set數據放入緩存** @param key    鍵* @param time   時間(秒)* @param values 值 可以是多個* @return 成功個數*/public long sSetAndTime(String key, long time, Object... values) {try {Long count = redisTemplate.opsForSet().add(key, values);if (time > 0)expire(key, time);return count;} catch (Exception e) {e.printStackTrace();return 0;}}/*** 獲取set緩存的長度** @param key 鍵*/public long sGetSetSize(String key) {try {return redisTemplate.opsForSet().size(key);} catch (Exception e) {e.printStackTrace();return 0;}}/*** 移除值為value的** @param key    鍵* @param values 值 可以是多個* @return 移除的個數*/public long setRemove(String key, Object... values) {try {Long count = redisTemplate.opsForSet().remove(key, values);return count;} catch (Exception e) {e.printStackTrace();return 0;}}// ===============================list=================================/*** 獲取list緩存的內容** @param key   鍵* @param start 開始* @param end   結束 0 到 -1代表所有值*/public List<Object> lGet(String key, long start, long end) {try {return redisTemplate.opsForList().range(key, start, end);} catch (Exception e) {e.printStackTrace();return null;}}/*** 獲取list緩存的長度** @param key 鍵*/public long lGetListSize(String key) {try {return redisTemplate.opsForList().size(key);} catch (Exception e) {e.printStackTrace();return 0;}}/*** 通過索引 獲取list中的值** @param key   鍵* @param index 索引 index>=0時, 0 表頭,1 第二個元素,依次類推;index<0時,-1,表尾,-2倒數第二個元素,依次類推*/public Object lGetIndex(String key, long index) {try {return redisTemplate.opsForList().index(key, index);} catch (Exception e) {e.printStackTrace();return null;}}/*** 將list放入緩存** @param key   鍵* @param value 值*/public boolean lSet(String key, Object value) {try {redisTemplate.opsForList().rightPush(key, value);return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 將list放入緩存* @param key   鍵* @param value 值* @param time  時間(秒)*/public boolean lSet(String key, Object value, long time) {try {redisTemplate.opsForList().rightPush(key, value);if (time > 0)expire(key, time);return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 將list放入緩存** @param key   鍵* @param value 值* @return*/public boolean lSet(String key, List<Object> value) {try {redisTemplate.opsForList().rightPushAll(key, value);return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 將list放入緩存** @param key   鍵* @param value 值* @param time  時間(秒)* @return*/public boolean lSet(String key, List<Object> value, long time) {try {redisTemplate.opsForList().rightPushAll(key, value);if (time > 0)expire(key, time);return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 根據索引修改list中的某條數據** @param key   鍵* @param index 索引* @param value 值* @return*/public boolean lUpdateIndex(String key, long index, Object value) {try {redisTemplate.opsForList().set(key, index, value);return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 移除N個值為value** @param key   鍵* @param count 移除多少個* @param value 值* @return 移除的個數*/public long lRemove(String key, long count, Object value) {try {Long remove = redisTemplate.opsForList().remove(key, count, value);return remove;} catch (Exception e) {e.printStackTrace();return 0;}}}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/209722.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/209722.shtml
英文地址,請注明出處:http://en.pswp.cn/news/209722.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

《師兄啊師兄》第二季確認定檔!海神揚名,穩健回歸!

近日&#xff0c;《師兄啊師兄》第二季的定檔海報和PV終于發布&#xff0c;確認將于12月14日上午10點強勢回歸&#xff01;這部備受矚目的國漫作品自第一季播出以來&#xff0c;便以其獨特的劇情設定和唯美的畫風&#xff0c;贏得了廣大觀眾的喜愛。如今&#xff0c;動畫第二季…

第一課【習題】給應用添加通知和提醒

構造進度條模板通知&#xff0c;name字段當前需要固定配置為downloadTemplate。 給通知設置分發時間&#xff0c;需要設置showDeliveryTime為false。 OpenHarmony提供后臺代理提醒功能&#xff0c;在應用退居后臺或退出后&#xff0c;計時和提醒通知功能被系統后臺代理接管…

Qt 5.15.2 三維顯示功能

Qt 5.15.2 三維顯示功能 三維顯示效果&#xff1a; .pro項目文件 QT core gui opengl 3dcore 3drender 3dinput 3dextrasgreaterThan(QT_MAJOR_VERSION, 4): QT widgetsCONFIG c17# You can make your code fail to compile if it uses deprecated APIs. # In ord…

2023年法國經銷商Solu-Watt來訪安科瑞-安科瑞 蔣靜

2023年4月10日上午9點&#xff0c;法國Solu-Watt公司Matthieu先生一行到安科瑞考察參觀工廠的智能化出入庫工作站、柔性化儀表生產車間及實驗室。自1992年以來&#xff0c;Solu-Watt在電氣設備市場中不斷發展。能夠提供量身定制的安裝有線電氣解決方案&#xff08;電氣柜、接線…

如何用Qt配置git項目并上傳Gitee

1.進入到Qt項目文件夾內&#xff0c;打開 “Git Bash Here” 2.初始化&#xff0c;在“Git Bash Here”中輸入 git init 3.加入所有文件&#xff0c;在“Git Bash Here”中輸入 git add . (需要注意&#xff0c;git add 后面還有一個點) 4.添加備注&#xff0c;git com…

STL源碼剖析筆記——哈希表、unordered_set、unordered_map、unordered_mutiset、unordered_mutimap

系列文章目錄 STL源碼剖析筆記——迭代器 STL源碼剖析筆記——vector STL源碼剖析筆記——list STL源碼剖析筆記——deque、stack&#xff0c;queue STL源碼剖析筆記——Binary Heap、priority_queue STL源碼剖析筆記——AVL-tree、RB-tree、set、map、mutiset、mutimap STL源…

一套rk3588 rtsp服務器推流的 github 方案及記錄 -01

我不生產代碼&#xff0c;我只是代碼的搬運工&#xff0c;相信我&#xff0c;看完這個文章你的圖片一定能變成流媒體推出去。 訴求&#xff1a;使用opencv拉流&#xff0c;轉成bgr數據&#xff0c;需要把處理后的數據&#xff08;BGR&#xff09;編碼成264&#xff0c;然后推流…

字符串函數strtok

1.調用格式&#xff1a; 2.調用形式&#xff1a;char*strtok(char*p1,const char*p2),其中第二個是由分隔符組成的字符串&#xff0c;第一個為需要分隔的字符串 3.調用目的&#xff1a;將分隔符之間的字符串取出 4.調用時一般將源字符串拷貝后調用&#xff0c;因為此函數會將…

基于Unity3D 低多邊形地形模型紋理貼圖

在線工具推薦&#xff1a; 3D數字孿生場景編輯器 - GLTF/GLB材質紋理編輯器 - 3D模型在線轉換 - Three.js AI自動紋理開發包 - YOLO 虛幻合成數據生成器 - 三維模型預覽圖生成器 - 3D模型語義搜索引擎 當談到游戲角色的3D模型風格時&#xff0c;有幾種不同的風格&#xf…

【工程實踐】使用modelscope下載大模型文件

前言 Modelscope&#xff08;魔搭社區&#xff09;是阿里達摩院的一款開源模型平臺&#xff0c;里面提供了很多的熱門模型供使用體驗&#xff0c;其中的模型文件可以通過git clone 快速下載。并且為模型提供了Notebook的快速開發體驗&#xff0c;使用阿里云服務&#xff0c;不需…

【優選算法系列】【專題二滑動窗口】第三節.904. 水果成籃和438. 找到字符串中所有字母異位詞

文章目錄 前言一、水果成籃 1.1 題目描述 1.2 題目解析 1.2.1 算法原理 1.2.2 代碼編寫 1.2.3 題目總結二、找到字符串中所有字母異位詞 2.1 題目描述 2.2 題目解析 2.2.1 算法原理 2.2.2 代碼編寫 …

SAP UI5 walkthrough step9 Component Configuration

在之前的章節中&#xff0c;我們已經介紹完了MVC的架構和實現&#xff0c;現在我們來講一下&#xff0c;SAPUI5的結構 這一步&#xff0c;我們將所有的UI資產從index.html里面獨立封裝在一個組件里面 這樣組件就變得獨立&#xff0c;可復用了。這樣&#xff0c;無所什么時候我…

隊列的實現

學習就像一段長跑&#xff0c;比的不是誰跑得快&#xff0c;而是誰更能堅持&#xff01;&#xff01; 1 隊列的概念及結構 隊列&#xff1a;只允許在一端進行插入數據操作&#xff0c;在另一端進行刪除數據操作的特殊線性表&#xff0c;隊列具有先進先出 FIFO(First In First O…

外網訪問內網服務器使用教程

如何在任何地方都能訪問自己家里的筆記本上的應用&#xff1f;如何讓局域網的服務器可以被任何地方訪問到&#xff1f;有很多類似的需求&#xff0c;我們可以統一用一個解決方案&#xff1a;內網穿透。內網穿透的工具及方式有很多&#xff0c;如Ngrok、Ssh、autossh、Natapp、F…

linux具體命令(一)

1. cd CD命令是Linux和類Unix操作系統中非常常用的一個命令&#xff0c;它的全稱是“change directory”&#xff0c;用于改變當前的工作目錄。用戶可以通過這個命令進入到不同的目錄中&#xff0c;進行文件操作或是執行其他任務。 以下是CD命令的一些基本用法&#xff1a; 進…

特殊進程之守護進程

文章目錄 1、守護進程的概念2、如何查看守護進程3、編寫守護進程的步驟3.1 創建子進程&#xff0c;父進程退出3.2 在子進程中創建新會話3.3 改變當前工作目錄3.4 重設文件權限掩碼3.5 關閉不需要的文件描述符3.6 某些特殊的守護進程打開/dev/null 4、守護進程代碼示例 1、守護進…

[UNILM]論文實現:Unified Language Model Pre-training for Natural Language.........

文章目錄 一、完整代碼二、論文解讀2.1 介紹2.2 架構2.3 輸入端2.4 結果 三、過程實現四、整體總結 論文&#xff1a;Unified Language Model Pre-training for Natural Language Understanding and Generation 作者&#xff1a;Li Dong, Nan Yang, Wenhui Wang, Furu Wei, Xia…

js new 原理

mdn new new 調用函數時&#xff0c;該函數將被用作構造函數 類只能用 new 運算符實例化 不使用 new 調用一個類將拋出 TypeError。 過程 new Foo(…) 執行時&#xff1a; 創建一個空的簡單 JavaScript 對象。 為方便起見&#xff0c;我們稱之為 newInstance。 如果構造函數…

華為OD機試真題-執行任務賺積分-2023年OD統一考試(C卷)

題目描述: 現有N個任務需要處理,同一時間只能處理一個任務,處理每個任務所需要的時間固定為1。 每個任務都有最晚處理時間限制和積分值,在最晚處理時間點之前處理完成任務才可獲得對應的積分獎勵。 可用于處理任務的時間有限,請問在有限的時間內,可獲得的最多積分。 輸入…

《LeetCode力扣練習》代碼隨想錄——字符串(替換數字---Java)

《LeetCode力扣練習》代碼隨想錄——字符串&#xff08;替換數字—Java&#xff09; 刷題思路來源于 代碼隨想錄 54. 替換數字 受制于語言限制&#xff0c;很普通的解法 import java.util.Scanner; class Main {public static void main(String[] args) {Scanner innew Scanner…