Redis Template使用append方法不起作用的解决办法以及序列化/反序列化的解释

今天使用Redis Template进行测试发现的问题,
遇到这个错

org.springframework.data.redis.serializer.SerializationException: Could not read JSON: 
Unrecognized token 'testtest': was expecting (JSON String, Number, Array, Object or token 'null', 'true' or 'false')


从github复制过来清除空格后解决,如果没有解决,下面配置序列化可能有所帮助。

调用该测试时出现append方法没用

   //不报错,append不管用
    @Test
    public void string5() {

        redisTemplate.opsForValue().set("k", "test");
        redisTemplate.opsForValue().append("k","test");
        System.out.println(redisTemplate.opsForValue().get("k"));
        redisTemplate.opsForValue().append("k","nihaoya");
        System.out.println(redisTemplate.opsForValue().get("k"));
    }

需要进行配置

 //值采用Json序列
        template.setValueSerializer(jackson2JsonRedisSerializer);

修改为如下形式得以解决

template.setValueSerializer(new StringRedisSerializer());

解释如下:

关于数据的“序列化/反序列化”,提供了多种可选择策略(RedisSerializer)

序列化/发序列化 解释
JdkSerializationRedisSerializer POJO对象的存取场景,使用JDK本身序列化机制,将pojo类通过ObjectInputStream/ObjectOutputStream进行序列化操作,最终redis-server中将存储字节序列。
StringRedisSerializer 适用于Key或者value为字符串的场景,根据指定的charset对数据的字节序列编码成string
JacksonJsonRedisSerializer 提供了javabean与json之间的转换能力,可以将pojo实例序列化成json格式存储在redis中,也可以将json格式的数据转换成pojo实例。
OxmSerializer 提供了将javabean与xml之间的转换能力,目前可用的三方支持包括jaxb,apache-xmlbeans;redis存储的数据将是xml工具。

上面4种策略中:

JdkSerializationRedisSerializerStringRedisSerializer是最基础的策略,在设计时仍然不推荐直接使用后面两种,即JacksonJsonRedisSerializerOxmSerializer,因为无论是json还是xml,他们本身仍然是String。

如果数据需要被第三方工具解析,那么数据应该使用StringRedisSerializer而不是JdkSerializationRedisSerializer

如果数据格式必须为json或者xml,那么在编程级别,在redisTemplate配置中仍然使用StringRedisSerializer,在存储之前或者读取之后,使用“SerializationUtils”工具转换转换成json或者xml

最后附上配置信息

 @Bean
    public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
        //配置连接工厂
        StringRedisTemplate template = new StringRedisTemplate(factory);

        //使用Jackson2JsonRedisSerializer来序列化和反序列化redis 的value值
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();

        //指定要序列化的域,field,get和set,以及修饰符范围
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        //om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);

        //指定序列化输入的类型,类必须是非final类
        om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance ,
                ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
        jackson2JsonRedisSerializer.setObjectMapper(om);

        //序列化配置为String格式
        template.setValueSerializer(new StringRedisSerializer());

        //
        template.setKeySerializer(new StringRedisSerializer());
        template.afterPropertiesSet();
        return template;
    }

参考博客:RedisTemplate用法详解

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章