redis數(shù)據(jù)存儲(chǔ)類型轉(zhuǎn)換異常排查與解決方案
在使用redis存儲(chǔ)點(diǎn)贊數(shù)據(jù)時(shí),常常遇到類型轉(zhuǎn)換異常Java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String。此問題源于Redis模板的序列化機(jī)制與存儲(chǔ)數(shù)據(jù)的類型不匹配。
問題描述:
后端代碼將點(diǎn)贊用戶ID (likeUserID)、被點(diǎn)贊文章ID (likePostID) 和被點(diǎn)贊回答ID (likeAnswerID) 存儲(chǔ)到Redis。RedisServiceImpl.java 中的 saveLiked2Redis 方法接收三個(gè) String 類型參數(shù),并將其作為 key 的一部分,使用 redisTemplate.opsForHash().put 方法將點(diǎn)贊狀態(tài)碼 Constant.REDIS_LIKE_CODE 存儲(chǔ)為 value。然而,Constant.REDIS_LIKE_CODE 是 Integer 類型,而 Redis 模板的默認(rèn)序列化器 StringRedisSerializer 期望 value 為 String 類型,導(dǎo)致類型轉(zhuǎn)換異常。
代碼片段:
RedisServiceImpl.java:
@Override public void saveLiked2Redis(String likeUserID, String likePostID, String likeAnswerID) { String key = RedisKeyUtils.getLikedKey(likeUserID, likePostID, likeAnswerID); redisTemplate.opsForHash().put(RedisKeyUtils.MAP_KEY_USER_LIKED, key, Constant.REDIS_LIKE_CODE); }
RedisLikeController.java:
// 點(diǎn)贊 @RequiresAuthentication @RequestMapping("/userLike") public ResponseJson userLike(@RequestBody UserLike userLike) { redisService.saveLiked2Redis(userLike.getLikeUserID(), userLike.getLikePostID(), userLike.getLikeAnswerID()); return new ResponseJson(Constant.HTTP_CODE_OK, null, "點(diǎn)贊成功"); }
UserLike.java:
public class UserLike { private Integer id;//主鍵ID private String likeUserID;//點(diǎn)贊人ID private String likePostID;//被點(diǎn)贊文章ID private String likeAnswerID;//被點(diǎn)贊回答ID private Integer status = 0;//點(diǎn)贊的狀態(tài),默認(rèn)未點(diǎn)贊0 0:未點(diǎn)贊 1:已點(diǎn)贊 //省略了構(gòu)造部分 }
錯(cuò)誤信息追蹤到 StringRedisSerializer 的 serialize 方法,證實(shí)了 Constant.REDIS_LIKE_CODE 的 Integer 類型無法直接轉(zhuǎn)換為 String 類型。
解決方案:
最直接的解決方法是將 Constant.REDIS_LIKE_CODE 定義為 String 類型,確保 Redis 存儲(chǔ)的 value 與序列化器期望的類型一致,從而避免類型轉(zhuǎn)換錯(cuò)誤。 另一種方法是修改 redisTemplate 的 value 序列化器為可以處理 Integer 類型的序列化器,例如 GenericJackson2JsonRedisSerializer。 選擇哪種方法取決于項(xiàng)目整體的設(shè)計(jì)和編碼風(fēng)格。