1. 程式人生 > 其它 >redis存入map型別資料預設序列化產生的問題

redis存入map型別資料預設序列化產生的問題

一、問題發現
專案中需要將部分資源存入redis中,資料型別為hash型別,程式碼使用的redisTemple。

Map map = new HashMap<String,Object>();
map.put("2021-03-12","100");
redisUtil.hashMultiSet("testHash",map);

redisUtil中的程式碼為

    public void hashMultiSet(final String key, Map<?, ?> map) {
        HashOperations<
String, Object, Object>
hash = redisTemplate.opsForHash(); hash.putAll(key, map); }

執行結果為

在這裡插入圖片描述
通過redis視覺化工具可以檢視到,所有的key和value還有hashkey和hashvalue的原始字元前,都加了一串字元。查了一下,這是JdkSerializationRedisSerializer進行序列化時,加上去的。
二、問題解決
通過查詢瞭解到現在可用的RedisSerializer主要有幾種:

(1)StringRedisSerializer

(2)Jackson2JsonRedisSerializer

(3)JdkSerializationRedisSerializer

(4)GenericToStringSerializer

(5)OxmSerializer
本次使用StringRedisSerializer來序列化和反序列化redis的key值,使用Jackson2JsonRedisSerializer來序列化和反序列化redis的value值(預設使用JDK的序列化方式)

package com.chinaunicom.utils;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.
jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.ObjectMapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 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.RedisOperations; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; /** * 建立自定義redisTemplate / @Configuration @ConditionalOnProperty(name = "jedis", havingValue = "true") @ConditionalOnClass(RedisOperations.class) public class RedisAutoConfig { private static Logger logger = LoggerFactory.getLogger(RedisAutoConfig.class); /** * 自定義redisTemplate,修改序列化方式 */ @Bean public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) { RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(redisConnectionFactory); // 使用Jackson2JsonRedisSerializer來序列化和反序列化redis的value值(預設使用JDK的序列化方式) Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer(Object.class); ObjectMapper mapper = new ObjectMapper(); mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); serializer.setObjectMapper(mapper); redisTemplate.setValueSerializer(serializer); redisTemplate.setHashValueSerializer(serializer); // 使用StringRedisSerializer來序列化和反序列化redis的key值 redisTemplate.setKeySerializer(new StringRedisSerializer()); redisTemplate.setHashKeySerializer(new StringRedisSerializer()); redisTemplate.afterPropertiesSet(); logger.info("Custom RedisTemplate success."); return redisTemplate; } @Bean @ConditionalOnBean(name = "redisTemplate") public RedisUtil redisUtils(RedisTemplate redisTemplate) { RedisUtil redisUtils = new RedisUtil(); redisUtils.setRedisTemplate(redisTemplate); return redisUtils; } }

配置類加上,完美解決當前問題