RedisTemplate存缓存数据时如何避免乱码问题?

2026-04-19 15:061阅读0评论SEO资源
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计820个文字,预计阅读时间需要4分钟。

RedisTemplate存缓存数据时如何避免乱码问题?

前言:RedisTemplate是Spring对Redis的封装。如图所示,RedisTemplate中定义了多种数据结构操作。redisTemplate.opsForList(); // 操作listredisTemplate.opsForValue(); // 操作字符串redisTemplate.opsForCluster(); // 集群操作

前言

RedisTemplate是Spring对于Redis的封装。

如上图所示,RedisTemplate中定义了对5种数据结构操作。

redisTemplate.opsForList();//操作list redisTemplate.opsForValue();//操作字符串 redisTemplate.opsForCluster();//集群时使用 redisTemplate.opsForGeo();//地理位置时使用 redisTemplate.opsForHash();//操作hash redisTemplate.opsForSet();//操作set redisTemplate.opsForZSet();//操作有序set

与StringRedisTemplate的区别

StringRedisTemplate继承RedisTemplate。

它们采用的序列化策略不同:

* StringRedisTemplate默认采用的是String的序列化策略,保存的key和value都是采用此策略序列化保存的。

* RedisTemplate默认采用的是JDK的序列化策略,保存的key和value都是采用此策略序列化保存的。

RedisTemplate和StringRedisTemplate它们存取的数据是相互独立的。

解决办法

上文已经提及,在动手的过程中,我采用的是RedisTemplate,在传递String类型的数据结构后,查看缓存会发现数据乱码现象。

这时候我们需要修改RedisTemplate的序列化策略。

RedisSerializer<String> stringSerializer = new StringRedisSerializer(); redisTemplate.setKeySerializer(stringSerializer); redisTemplate.setValueSerializer(stringSerializer); redisTemplate.setHashKeySerializer(stringSerializer); redisTemplate.setHashValueSerializer(stringSerializer);

但是注意一点,由于采用了String的序列化策略,所以只接受value值类型为String的参数。

如果像我一样传递了Integer类型的参数,直接使用toString()方法存入缓存。

ops.set("stock", redPacket.getStock().toString(),TIME_OUT, TimeUnit.SECONDS);

RedisTemplate存缓存数据时如何避免乱码问题?

这样就解决了乱码问题。

附:SpringBoot启动实例化配置

@Configuration public class RedisConfigurtion { @Autowired private RedisTemplate redisTemplate; @Bean public RedisTemplate<String, Object> stringSerializerRedisTemplate() { RedisSerializer<String> stringSerializer = new StringRedisSerializer(); redisTemplate.setKeySerializer(stringSerializer); redisTemplate.setValueSerializer(stringSerializer); redisTemplate.setHashKeySerializer(stringSerializer); redisTemplate.setHashValueSerializer(stringSerializer); return redisTemplate; } }

补充:redis key和value的乱码问题解决,含日期转化格式问题

在项目中,遇到的问题是redis的key和value出现的乱码问题:

而原本的内容为下:

{ "status":"success", "data":{ "id":3, "title":"花林", "price":99, "stock":81, "description":"美女一只", "sales":17, "imgUrl":"xiaolei1996.oss-cn-shanghai.aliyuncs.com/blog/title/we1.jpg", "promoStatus":2, "promoPrice":50, "promoId":1, "startDate":"2020-03-23 21:50:59" } }

原因:

是因为和redis内部的编码协议出现了问题,所以需要改进。spring提供了一个优化方案。

springboot的redisTemplate改进。

@Component @EnableRedisHttpSession(maxInactiveIntervalInSeconds = 3600) public class RedisConfig { @Bean public RedisTemplate redisTemplate(RedisConnectionFactory factory){ RedisTemplate redisTemplate = new RedisTemplate(); redisTemplate.setConnectionFactory(factory); //首先解决key的序列化问题 StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); redisTemplate.setKeySerializer(stringRedisSerializer); //解决value的序列化问题 Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); redisTemplate.setValueSerializer(jackson2JsonRedisSerializer); return redisTemplate; } }

比之前好了,但是还有点小问题,json的数据比以前多了,这是因为日期的转化出现问题,这块的知识触及盲区,就先把解决方案写下面,以后有时间在研究。

public class JodaDateTimeJsonSerializer extends JsonSerializer<DateTime> { @Override public void serialize(DateTime value, JsonGenerator gen, SerializerProvider serializers) throws IOException { gen.writeString(value.toString("yyyy-MM-dd HH:mm:ss")); } }

public class JodaDateTimeJsonDeserializer extends JsonDeserializer<DateTime> { @Override public DateTime deserialize(JsonParser p, DeserializationContext ctxt ) throws IOException, JsonProcessingException { String dateString= p.readValueAs(String.class); DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss"); return DateTime.parse(dateString,dateTimeFormatter);//转成 } }

@Component @EnableRedisHttpSession(maxInactiveIntervalInSeconds = 3600) public class RedisConfig { @Bean public RedisTemplate redisTemplate(RedisConnectionFactory factory){ RedisTemplate redisTemplate = new RedisTemplate(); redisTemplate.setConnectionFactory(factory); //首先解决key的序列化问题 StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); redisTemplate.setKeySerializer(stringRedisSerializer); //解决value的序列化问题 Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); redisTemplate.setValueSerializer(jackson2JsonRedisSerializer); //改进日期转化问题 ObjectMapper objectMapper = new ObjectMapper(); SimpleModule simpleModule = new SimpleModule(); simpleModule.addSerializer(DateTime.class,new JodaDateTimeJsonSerializer()); simpleModule.addDeserializer(DateTime.class,new JodaDateTimeJsonDeserializer()); //解决反序列化问题 objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); objectMapper.registerModule(simpleModule); jackson2JsonRedisSerializer.setObjectMapper(objectMapper); redisTemplate.setValueSerializer(jackson2JsonRedisSerializer); return redisTemplate; } }

最后终于出现了预期的效果

以上为个人经验,希望能给大家一个参考,也希望大家多多支持易盾网络。如有错误或未考虑完全的地方,望不吝赐教。

本文共计820个文字,预计阅读时间需要4分钟。

RedisTemplate存缓存数据时如何避免乱码问题?

前言:RedisTemplate是Spring对Redis的封装。如图所示,RedisTemplate中定义了多种数据结构操作。redisTemplate.opsForList(); // 操作listredisTemplate.opsForValue(); // 操作字符串redisTemplate.opsForCluster(); // 集群操作

前言

RedisTemplate是Spring对于Redis的封装。

如上图所示,RedisTemplate中定义了对5种数据结构操作。

redisTemplate.opsForList();//操作list redisTemplate.opsForValue();//操作字符串 redisTemplate.opsForCluster();//集群时使用 redisTemplate.opsForGeo();//地理位置时使用 redisTemplate.opsForHash();//操作hash redisTemplate.opsForSet();//操作set redisTemplate.opsForZSet();//操作有序set

与StringRedisTemplate的区别

StringRedisTemplate继承RedisTemplate。

它们采用的序列化策略不同:

* StringRedisTemplate默认采用的是String的序列化策略,保存的key和value都是采用此策略序列化保存的。

* RedisTemplate默认采用的是JDK的序列化策略,保存的key和value都是采用此策略序列化保存的。

RedisTemplate和StringRedisTemplate它们存取的数据是相互独立的。

解决办法

上文已经提及,在动手的过程中,我采用的是RedisTemplate,在传递String类型的数据结构后,查看缓存会发现数据乱码现象。

这时候我们需要修改RedisTemplate的序列化策略。

RedisSerializer<String> stringSerializer = new StringRedisSerializer(); redisTemplate.setKeySerializer(stringSerializer); redisTemplate.setValueSerializer(stringSerializer); redisTemplate.setHashKeySerializer(stringSerializer); redisTemplate.setHashValueSerializer(stringSerializer);

但是注意一点,由于采用了String的序列化策略,所以只接受value值类型为String的参数。

如果像我一样传递了Integer类型的参数,直接使用toString()方法存入缓存。

ops.set("stock", redPacket.getStock().toString(),TIME_OUT, TimeUnit.SECONDS);

RedisTemplate存缓存数据时如何避免乱码问题?

这样就解决了乱码问题。

附:SpringBoot启动实例化配置

@Configuration public class RedisConfigurtion { @Autowired private RedisTemplate redisTemplate; @Bean public RedisTemplate<String, Object> stringSerializerRedisTemplate() { RedisSerializer<String> stringSerializer = new StringRedisSerializer(); redisTemplate.setKeySerializer(stringSerializer); redisTemplate.setValueSerializer(stringSerializer); redisTemplate.setHashKeySerializer(stringSerializer); redisTemplate.setHashValueSerializer(stringSerializer); return redisTemplate; } }

补充:redis key和value的乱码问题解决,含日期转化格式问题

在项目中,遇到的问题是redis的key和value出现的乱码问题:

而原本的内容为下:

{ "status":"success", "data":{ "id":3, "title":"花林", "price":99, "stock":81, "description":"美女一只", "sales":17, "imgUrl":"xiaolei1996.oss-cn-shanghai.aliyuncs.com/blog/title/we1.jpg", "promoStatus":2, "promoPrice":50, "promoId":1, "startDate":"2020-03-23 21:50:59" } }

原因:

是因为和redis内部的编码协议出现了问题,所以需要改进。spring提供了一个优化方案。

springboot的redisTemplate改进。

@Component @EnableRedisHttpSession(maxInactiveIntervalInSeconds = 3600) public class RedisConfig { @Bean public RedisTemplate redisTemplate(RedisConnectionFactory factory){ RedisTemplate redisTemplate = new RedisTemplate(); redisTemplate.setConnectionFactory(factory); //首先解决key的序列化问题 StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); redisTemplate.setKeySerializer(stringRedisSerializer); //解决value的序列化问题 Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); redisTemplate.setValueSerializer(jackson2JsonRedisSerializer); return redisTemplate; } }

比之前好了,但是还有点小问题,json的数据比以前多了,这是因为日期的转化出现问题,这块的知识触及盲区,就先把解决方案写下面,以后有时间在研究。

public class JodaDateTimeJsonSerializer extends JsonSerializer<DateTime> { @Override public void serialize(DateTime value, JsonGenerator gen, SerializerProvider serializers) throws IOException { gen.writeString(value.toString("yyyy-MM-dd HH:mm:ss")); } }

public class JodaDateTimeJsonDeserializer extends JsonDeserializer<DateTime> { @Override public DateTime deserialize(JsonParser p, DeserializationContext ctxt ) throws IOException, JsonProcessingException { String dateString= p.readValueAs(String.class); DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss"); return DateTime.parse(dateString,dateTimeFormatter);//转成 } }

@Component @EnableRedisHttpSession(maxInactiveIntervalInSeconds = 3600) public class RedisConfig { @Bean public RedisTemplate redisTemplate(RedisConnectionFactory factory){ RedisTemplate redisTemplate = new RedisTemplate(); redisTemplate.setConnectionFactory(factory); //首先解决key的序列化问题 StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); redisTemplate.setKeySerializer(stringRedisSerializer); //解决value的序列化问题 Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); redisTemplate.setValueSerializer(jackson2JsonRedisSerializer); //改进日期转化问题 ObjectMapper objectMapper = new ObjectMapper(); SimpleModule simpleModule = new SimpleModule(); simpleModule.addSerializer(DateTime.class,new JodaDateTimeJsonSerializer()); simpleModule.addDeserializer(DateTime.class,new JodaDateTimeJsonDeserializer()); //解决反序列化问题 objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); objectMapper.registerModule(simpleModule); jackson2JsonRedisSerializer.setObjectMapper(objectMapper); redisTemplate.setValueSerializer(jackson2JsonRedisSerializer); return redisTemplate; } }

最后终于出现了预期的效果

以上为个人经验,希望能给大家一个参考,也希望大家多多支持易盾网络。如有错误或未考虑完全的地方,望不吝赐教。