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()

总结

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

相关文章

  • java Servlet 实现动态验证码图片示例

    java Servlet 实现动态验证码图片示例

    这篇文章主要介绍了java Servlet 实现动态验证码图片示例的资料,这里整理了详细的代码,有需要的小伙伴可以参考下。
    2017-02-02
  • IDEA简单实现登录注册页面

    IDEA简单实现登录注册页面

    这篇文章主要介绍了IDEA简单实现登录注册页面,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-12-12
  • Java 中使用Spring Security的实例详解

    Java 中使用Spring Security的实例详解

    Spring Security是一款强大的安全框架,可以帮助用户保护Web应用程序和REST API的安全性,这篇文章主要介绍了Java 中如何使用Spring Security,需要的朋友可以参考下
    2023-06-06
  • Netty分布式Server启动流程服务端初始化源码分析

    Netty分布式Server启动流程服务端初始化源码分析

    本章主要讲解server启动的关键步骤, 读者只需要了解server启动的大概逻辑, 知道关键的步骤在哪个类执行即可, 并不需要了解每一步的运作机制, 之后会对每个模块进行深度分析
    2022-03-03
  • Java如何使用Optional与Stream取代if判空逻辑(JDK8以上)

    Java如何使用Optional与Stream取代if判空逻辑(JDK8以上)

    这篇文章主要给大家介绍了关于Java如何使用Optional与Stream取代if判空逻辑(JDK8以上)的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Java具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-09-09
  • SpringBoot+MinIO实现文件上传、读取、下载、删除的使用示例

    SpringBoot+MinIO实现文件上传、读取、下载、删除的使用示例

    本文主要介绍了SpringBoot+MinIO实现文件上传、读取、下载、删除的使用示例,详细介绍每个功能实现的步骤和代码示例,具有一定的参考价值,感兴趣的可以了解一下
    2023-10-10
  • Java中List与数组相互转换实例分析

    Java中List与数组相互转换实例分析

    这篇文章主要介绍了Java中List与数组相互转换的方法,实例分析了Java中List与数组相互转换中容易出现的问题与相关的解决方法,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-05-05
  • Java Web学习之Cookie和Session的深入理解

    Java Web学习之Cookie和Session的深入理解

    这篇文章主要给大家介绍了关于Java Web学习之Cookie和Session的相关资料,需要的朋友可以参考下
    2018-04-04
  • Java中FileOutputStream流的write方法

    Java中FileOutputStream流的write方法

    这篇文章主要为大家详细介绍了Java中FileOutputStream流的write方法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-08-08
  • Java基于Swing实现的打猎射击游戏代码

    Java基于Swing实现的打猎射击游戏代码

    这篇文章主要介绍了Java基于Swing实现的打猎射击游戏代码,包含完整的游戏事件处理与逻辑流程控制,具有不错的参考借鉴价值,需要的朋友可以参考下
    2014-11-11

最新评论