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用法詳解

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