使用Redis和jackson操作json中遇到的坑

时间:2021-01-11 08:04:25

  前言(可以略过)

  最近在开发一个智能电表的管理系统,与常规的面向业务的系统不同。智能电表特点是每30分钟会向服务器发一次请求,报道自己目前的电表情况。然后服务器根据电表情况统计此电表的电量使用情况,包括日,月,年。不同的小区还有不同的阶梯峰谷电计算策略。不同的缴费时间(需要根据缴费时间生成对应的订单)。并且电表初期预计有10w个,这样就又带来了高并发的问题。

  所以此系统主要难点就是实时电量的统计以及高并发。

  经过一系列的讨论,终于找到了解决方案:通过redis来对所有的电表数据进行缓存,然后一天进行一次持久化,这样的话就可以减少mysql的压力,但弊端就是redis的数据结构会比较复杂。

  正文(问题描述)

  在用redis存储获取数据时,发现从redis存入的json字符串无法使用jackson进行对象转换。一开始以为是jackson的使用问题,然后又是看谷歌又是看文档,发现都无法解决。最终debug发现了问题如下:

  当把一个对象转换成Json字符串存入redis中,然后再从redis取出时是这样的格式

要转换的对象
class A{
    int consumeStep=0;
    float totalAmount=0f;
}

从redis中取出后的数据格式:

"{\"consumeStep\":1,\"totalAmount\":0.0}"

可以发现,字符串进行了转义处理。

如果直接把转义的字符串显式赋值给一个变量,编译器会自动把转义字符去除,变成一个正常的json字符:

使用Redis和jackson操作json中遇到的坑

如果不是显式赋值的,那么原来的转义字符以及开头和结束的双引号都会存在

使用Redis和jackson操作json中遇到的坑

如果上面的格式想通过显式赋值,要怎么实现呢?需要把每一个转义字符再次转义如下:

String c="\"{\\\"consumeStep\\\":1,\\\"totalAmount\\\":0.0}\"";

使用Redis和jackson操作json中遇到的坑

那么问题也就解决了,因为不是显式赋值的原因,所以从redis中获取的json字符串会出现多余的双引号和转义字符,造成jackson无法识别解析,解决方法就是把多余的字符去掉:

str=str.substring(1, structureString.length()-1);//去掉开头和结尾的双引号
str=str.replace("\\", "");//去掉转义字符

暂时只能想到这个方法,有更牛方法的同学欢迎留言,一起学习,谢谢。