Java使用RedisTemplate操作Redis遇到的坑

 更新时间:2023年12月20日 09:28:50   作者:trusause  
这篇文章主要介绍了Java使用RedisTemplate操作Redis遇到的坑,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

坑一

方法:

直接使用注入的方式       

@AutoWired
private RedisTemplate redisTemplate;

异常现象:

key会出现乱码

127.0.0.1:6379> keys *

1) "\xac\xed\x00\x05t\x00\x04name"

原因:

spring-data-redis的RedisTemplate<K, V>模板类在操作redis时默认使用JdkSerializationRedisSerializer来进行序列化

解决:

自定义RestTemplate,使用GenericJackson2JsonRedisSerializer解决序列化问题,注入的@AutoWired private RedisTemplate redisTemplate;其实是自定义的RestTemplate,

注意事项:

@Bean注入的bean是方法名,所以要目方法名写成restTemplate,要么写自定义的(如restTemplateInit()),在注入的时候就要用@Resources(name="restTemplateInit")

package com.example.demo.config;
 
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
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.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Component;
 
@Data
@Component
@Configuration
@Slf4j
public class RedisConfig {
 
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);
 
//        // 使用Jackson2JsonRedisSerialize 替换默认序列化
//        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
//
//        ObjectMapper objectMapper = new ObjectMapper();
//        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
//        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
//
//        jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
 
        GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
 
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
 
        // 设置value的序列化规则和 key的序列化规则
        redisTemplate.setKeySerializer(stringRedisSerializer);
        redisTemplate.setValueSerializer(genericJackson2JsonRedisSerializer);
 
        redisTemplate.setHashKeySerializer(stringRedisSerializer);
        redisTemplate.setHashValueSerializer(genericJackson2JsonRedisSerializer);
 
        redisTemplate.setDefaultSerializer(genericJackson2JsonRedisSerializer);
        redisTemplate.setEnableDefaultSerializer(true);
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }
 
}

坑二、用StringRedisTemplate和RedisTemplate取值赋值问题

redisTemplate.opsForValue().set("test1", "123");
redisTemplate.opsForValue().set("test2", ayUser);
//stringRedisTemplate.opsForValue().set("test3", "{\"name\":\"jack\"}");
//value设置成{\"name\":\"jack\"}这样的json也没用,需要带上序列化的类,像下面这样
stringRedisTemplate.opsForValue().set("test3", "{\"@class\":\"com.example.demo.model.AyUser\",\"id\":null,\"name\":\"shenzhen\",\"password\":null}");
 
System.out.println((String) redisTemplate.opsForValue().get("test1"));//123
System.out.println(stringRedisTemplate.opsForValue().get("test1"));//"123"
System.out.println((AyUser) redisTemplate.opsForValue().get("test2"));//AyUser(id=null, name=shenzhen, password=null)
System.out.println(redisTemplate.opsForValue().get("test3"));//AyUser(id=null, name=shenzhen, password=null)
System.out.println(stringRedisTemplate.opsForValue().get("test3"));//{"@class":"com.example.demo.model.AyUser","id":null,"name":"shenzhen","password":null}

使用上面注入的自定义的RedisTemplate都是可以反序列化成功的,如下!

但是使用的stringRedisTemplate虽然set的是返祖json格式的且带序列化的,但是不能直接通过强转实现(AyUser),需要通过com.alibaba.fastjson.JSON去反序列化

AyUser ayUser_3_0 = JSON.parseObject(stringRedisTemplate.opsForValue().get("test3_0"), AyUser.class);

通过ayUser_3_0.getName()就可以取到。

AyUser ayUser_2 = (AyUser) redisTemplate.opsForValue().get("test2");//ayUser_2.getName()
AyUser ayUser_3 = (AyUser) redisTemplate.opsForValue().get("test3");//ayUser_3.getName()

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • SpringBoot如何使用mica-xss防止Xss攻击

    SpringBoot如何使用mica-xss防止Xss攻击

    这篇文章主要介绍了SpringBoot如何使用mica-xss防止Xss攻击问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-01-01
  • 解决IDEA项目external libraries依赖包消失的问题

    解决IDEA项目external libraries依赖包消失的问题

    有时候电脑重启后,再打开IDEA上的项目时会出现external libraries目录下的依赖包都消失了的情况,只剩下了一个JDK的包,本文给大家介绍了解决IDEA项目external libraries依赖包消失的办法,需要的朋友可以参考下
    2024-02-02
  • 使用Spring AOP实现用户操作日志功能

    使用Spring AOP实现用户操作日志功能

    这篇文章主要介绍了使用Spring AOP实现了用户操作日志功能,功能实现需要一张记录日志的log表,结合示例代码给大家讲解的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-05-05
  • Java实现人机对战猜拳游戏

    Java实现人机对战猜拳游戏

    这篇文章主要为大家详细介绍了Java实现人机对战猜拳游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-07-07
  • spring和quartz整合,并简单调用(实例讲解)

    spring和quartz整合,并简单调用(实例讲解)

    下面小编就为大家带来一篇spring和quartz整合,并简单调用(实例讲解)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-07-07
  • Java实现List去重的方法详解

    Java实现List去重的方法详解

    本文用示例介绍Java的List(ArrayList、LinkedList等)的去重的方法。List去重的常用方法一般是:JDK8的stream的distinct、转为HashSet、转为TreeSet等,感兴趣的可以了解一下
    2022-05-05
  • Java中HashMap和Hashtable的区别小结

    Java中HashMap和Hashtable的区别小结

    本文主要介绍了Java中HashMap和Hashtable的区别小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-07-07
  • Maven3种打包方式中maven-assembly-plugin的使用详解

    Maven3种打包方式中maven-assembly-plugin的使用详解

    这篇文章主要介绍了Maven3种打包方式中maven-assembly-plugin的使用,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-07-07
  • 每天学Java!一分钟了解JRE与JDK

    每天学Java!一分钟了解JRE与JDK

    每天学Java!一分钟了解JRE与JDK,什么是JRE?什么是JDK?什么是JVM?相信通过本文大家都会有所了解,感兴趣的小伙伴们可以参考一下
    2016-07-07
  • Java并发编程中的CyclicBarrier使用解析

    Java并发编程中的CyclicBarrier使用解析

    这篇文章主要介绍了Java并发编程中的CyclicBarrier使用解析,CyclicBarrier从字面意思上来看,循环栅栏,这篇文章就来分析下是到底是如何实现循环和栅栏的,需要的朋友可以参考下
    2023-12-12

最新评论