关于SpringRedis序列化器的问题

起因是我在项目部署的时候有一个接口,本地跑起来没有问题,在linux服务器上面一开始跑起来也没有问题,后面突然就报错了。问同事说也没有另外部署覆盖我的接口。

后面排查是同事提供了一个rpc接口,这个接口有修改RedisTemplate 序列化器的代码,调完那个rpc接口,再调这个接口就会出现序列化的问题。然后进行代码自测,发现里面存在一些以前没注意的问题。

RedisTemplate的定义如下

@Configuration
public class RedisConfig {

    @Bean("redisTemplate")
    //一开始以为是没有加@Primary注解的缘故,导致系统不知道使用哪一个RedisTemplate,后面发现不是,就也没有注释掉
    @Primary
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(factory);
        //om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        template.setKeySerializer(RedisSerializer.string());
        template.setHashKeySerializer(RedisSerializer.string());
        template.setValueSerializer(RedisSerializer.json());
        template.setHashValueSerializer(RedisSerializer.json());
        template.afterPropertiesSet();
        return template;
    }

    @Bean("redisStringTemplate")
    public RedisTemplate<String, String> redisStringTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, String> template = new RedisTemplate<>();
        template.setConnectionFactory(factory);
        template.setKeySerializer(RedisSerializer.string());
        template.setHashKeySerializer(RedisSerializer.string());
        template.setValueSerializer(RedisSerializer.string());
        template.setHashValueSerializer(RedisSerializer.string());
        template.afterPropertiesSet();
        return template;
    }
}

进行redis测试的代码

@SpringBootTest(classes = XiotDeviceApplication.class)
public class RedisTest {
    @Resource(name = "redisStringTemplate")
    RedisTemplate<String, String> stringTemplate;

    @Resource(name = "redisTemplate")
    private RedisTemplate<String, Object> redisTemplate;

    @Test
    public void redisTest2() {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("123", "asd");
        jsonObject.put("234", "fff");
        stringTemplate.opsForValue().set("yu", jsonObject.toJSONString());
        redisTemplate.opsForValue().set("yu2",jsonObject.toJSONString());
        redisTemplate.opsForValue().set("yu3",jsonObject);
        String yu = stringTemplate.opsForValue().get("yu");
        String yu2 = stringTemplate.opsForValue().get("yu2");
        Object yu3 = redisTemplate.opsForValue().get("yu3");
        Object yu4 = redisTemplate.opsForValue().get("yu2");
        System.out.println("yu4 = " + yu4);
    }
}

生成的代码结果

一开始我感觉非常奇怪,明明是字符串格式化的存到redis变成了json格式,而使用json格式化的却变成了字符串格式。非常不能理解。

直到我测试了key=yu3的redis数据想通了

key=yu的数据存储都是字符串序列化,取出来也是字符串的格式 只是我使用的redis查看工具会做一个格式化的展示。

key=yu2的数据,使用json序列化,但是存储的数据是字符串,存到redis里面也是字符串,会对原有的双引号做转义,数据取出来的时候就会出现转义符。

key=yu3的数据,使用json序列化,存储的数据是对象,在redis里面也是字符串,查看工具本身做了格式化展示。但是会加上"@class": "com.alibaba.fastjson.JSONObject"标识是哪一个类,这样在取出来的时候也会序列化成指定的类。

总结:使用opsForValue()存储到redis里面的都是string格式,但是一些redis连接工具会对展示做格式化,序列化器使用在jvm中,跟redis存储没有什么关系,负责什么样的字符存储到redis或redis中读出来的字符展现成什么样。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值