Redis采用ZSet存入JSON字符串,取出后反序列化报错即解决方案

Redis 使用ZSet数据结构保存JSON格式的数据,在入到Redis后反序列化时发生了错误:

 原因是到Redis中存储时,给每一个字段前加上了反斜杠,不能直接使用JSON直接反序列化。

可以使用JSON.parse()方法在反序列化之前,对于字符串解析一下即可。

int setNum = (page - 1) * size / 20000;
int from = (page - 1) * size % 20000;
List<Object> zSetByRange = redisUtil.getZSetByRange("redis keyName",from,from+size-1);
Object parse = JSON.parse(zSetByRange.toString());
list= JSON.parseArray(JSON.toJSONString(parse), 反序列化的类.class);

redisUtil.getZSetByRange:等价于以下代码段

public List<Object> getZSetByRange(String key, int start, int end){
    Set<Object> range = redisTemplate.opsForZSet().range(key, start, end);
    return new ArrayList<>(range);
}

报错信息:

com.alibaba.fastjson.JSONException: field null expect '[', but string, pos 2509, line 1, column 2510"[{\"..............

下附一个Redis Template API支持的批量插入的代码模板:

/**批量保存至Redis*/
public <T>void saveDataToRedis(List<T> list,String setName) {
    RedisSerializer<String> keySerializer = (RedisSerializer<String>)redisTemplate.getKeySerializer();
    RedisSerializer<String> valueSerializer = (RedisSerializer<String>)redisTemplate.getValueSerializer();
//获取插入开始时间戳
    long startTime = System.currentTimeMillis();
    redisTemplate.executePipelined((RedisCallback<String>) connection -> {
        for (int i = 0; i < list.size(); i++) {
            connection.zSetCommands().zAdd(keySerializer.serialize(setName),i,valueSerializer.serialize(JSON.toJSONString(list.get(i))));
        }
        //设置超时时间
        connection.expire(keySerializer.serialize(setName), 3600L);
        return null;
    });
//获取插入结束时间戳,打印日志
    long endTime = System.currentTimeMillis();
    long costTime = endTime - startTime;
    log.info(">>>>>>saveDataToRedis add into redis by using pipeline for loop spent->" + costTime);
}

版权声明:本文为qq_39004108原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。