(原创)Java使用RedisTemplate操作Redis的那些坑

2 篇文章 0 订阅

坑一、

    方法:

    直接使用注入的方式       

@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()
  • 5
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值