Redis缓存复杂对象解决办法

概述

redis缓存简单对象很容易,但对于复杂对象,如果想和简单对象一样,直接将复杂对象转成JSON字符串,那很容易出现cannot be cast to java.XXX.XXX,也就是ClassCastException类型转换异常,或者是该复杂对象从redis中取出后,直接通过含有@RestController注解的Controller返回给前端,那么前端接收后会出现大量反斜杠。

这一问题在开发WHITE’S时,就时常出现,看到网上也没有什么很好的解决办法,所以我写一下自己的解决办法。

例如:使用mybatis-plus的分页对象IPage时,IPage内部有一个List集合对象Records,Records封装的是一个个的分页文章对象PaginationDto。

IPage<PaginationDto> pageData = new Page<>();
List<PaginationDto> records = pageData.getRecords();

ClassCastException类型转换异常原因

将上述pageData直接缓存到redis中,然后从redis中获取数据,得出的pageData字符串再强制转换回IPage类型,就会出现cannot be cast to java.XXX.XXX,因为存在多级嵌套对象。

            redisTemplate.opsForValue().set("pageData", JSONUtil.toJsonStr(pageData));
            Object data = redisTemplate.opsForValue().get("pageData");
            pageData = (IPage<PaginationDto>) data;//报错代码

前端接收pageData现大量反斜杠原因

将上述pageData直接缓存到redis中,然后从redis中获取数据后不做强转,直接返回这个对象,例如:

  	    redisTemplate.opsForValue().set("pageData", JSONUtil.toJsonStr(pageData));
            Object data = redisTemplate.opsForValue().get("pageData");
            return data;

注意,JSONUtil.toJsonStr(pageData)代表pageData对象第一次被转义成字符串对象,由于@RestController包含@ResponseBody注解,会经过第二次转义,也就是pageData被第二次转义,那么pageData字符串对象内部如果有双引号“""”这种歧义的标识,那么会被转义成反斜杠"\",所以前端接收pageData字符串对象时会出现大量反斜杠。

这种问题的解决方式,可以从前端入手,前端将反斜杠去掉(因为后端pageData是不会出现反斜杠,后端的pageData只经过一次转义),但具体操作我没有试过,网上有一些解答,但成功与否就不得而知了。

毕竟作为后端,还是以后端解决问题为主,下面来说明后端的解决方式。

对象拆分解决redis存储复杂对象问题

由于redis存储简单对象可以正常强转,那么照这个思路,只要将复杂对象转变为简单对象存储、将简单对象重新封装成复杂对象即可。

我选用了hash类型存储简单对象,因为key-的数据格式方便我的分页操作(但是hash会出现顺序问题,本人自己排了序,可以选用list)。

//拆分保存方法saveByRedis(pageData,"all_deleted_0");
    public void saveByRedis(IPage<PaginationDto> pageData, String redisHash){
        //保存的key-value集合
        Map<Object, Object> result = new HashMap<>();
	//pageData对象中拆分文章对象
        List<PaginationDto> paginationDtoList = pageData.getRecords();
        for (PaginationDto paginationDto:paginationDtoList
        ) {
            //key为博客id,value为PaginationDto对象
            result.put(paginationDto.getId().toString(),paginationDto);
        }
        //将博客对象存入redis
        redisTemplate.opsForHash().putAll(redisHash,result);
        ...
    }

//封装回复杂对象方法getByRedis
  public IPage<PaginationDto> getByRedis(IPage<PaginationDto> pageData,Map<Object, Object> value){
        //重新封装博客数据进行分页的list集合
        List<PaginationDto> returnList = new ArrayList<>();
        //遍历集合,value是从redis中key=all_deleted_0对应的拆分对象map
        Set<Object> keySet = value.keySet();
        System.out.println(keySet.toString()+"+++++++++++++++++++++");
        for (Object key:keySet
        ) {
            System.out.println(key.toString()+"-------------------------------");
	    //强制转换简单对象
            PaginationDto o = (PaginationDto) value.get(key);
            //重新封装回List<PaginationDto>
            returnList.add(o);
        }
	...
    }

通过saveByRedis方法,拆分出PaginationDto文章分页对象,将它们存入redis,获取时,用getByRedis方法从redis缓存中取出对应的PaginationDto对象,然后封装回List集合,最后再将List封装回pageData对象即可(这里步骤省略)。

如果大家还有什么好的解决办法可以互相分享一下!

欢迎踩一踩我的博客~
WHITE’S

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
PHP(全称:PHP: Hypertext Preprocessor)是一种广泛应用于Web开发的开源脚本语言,以其易学易用、高效灵活的特性深受广大开发者喜爱。诞生于1995年,由Rasmus Lerdorf创建,PHP最初用于简单的网页动态处理,如今已发展成为一款功能齐全、生态丰富的全栈开发工具,支持从网站前端交互到后端业务逻辑、数据库操作乃至API接口开发的全方位需求。 PHP的一大特点在于其与HTML的深度融合,可以直接嵌入到HTML文档中,通过特殊的起始标签“<?php”和结束标签“?>”界定PHP代码段。这种特性使得开发者能够轻松地在静态网页中插入动态内容,实现数据渲染、条件判断、循环处理等功能,极大地简化了Web开发流程。同时,PHP也支持纯脚本文件编写,适用于构建复杂的后台逻辑。 PHP语法简洁明了,借鉴了C、Perl等语言的特点,易于理解和学习,对于初学者友好。它支持面向过程、面向对象以及函数式编程范式,可根据项目需求和开发者喜好灵活选择。PHP内置丰富的数据类型(如整型、浮点型、字符串、数组、对象等),并提供了大量的预定义函数,涵盖了字符串操作、数学运算、文件系统处理、日期时间处理、数据库连接等常见功能,极大提高了开发效率。 在Web开发中,PHP与MySQL数据库的搭配尤为经典。PHP提供mysqli、PDO等数据库扩展,能够无缝连接MySQL,进行SQL查询、数据插入、更新、删除等操作,实现动态网站的数据持久化。此外,PHP还支持与其他数据库系统的连接,如PostgreSQL、SQLite、Oracle等,具有良好的数据库兼容性。 PHP拥有庞大的开发者社区和丰富的开源项目,如内容管理系统(CMS)WordPress、Drupal、Joomla,框架 Laravel、Symfony、CodeIgniter等,为开发者提供了丰富的代码资源和快速开发的便利。同时,官方维护的PHP文档详尽全面,社区活跃的技术论坛和问答网站为学习和解决问题提供了有力支持。 在性能优化方面,PHP支持 opcode 缓存(如APC、OpCache)以加速脚本执行,可通过配置调整、代码优化、使用缓存技术等手段提升应用性能。近年来,PHP持续进行性能改进与新特性的引入,如PHP 7系列版本在速度上有了显著提升,新增了类型声明、标量类型提示、null合并运算符等语法特性,进一步提升了开发效率和代码质量。 总的来说,PHP作为一种成熟的Web开发语言,凭借其易用性、灵活性、丰富的库与框架支持、强大的社区生态以及持续的性能优化,成为了构建各类动态网站、Web应用及API服务的理想选择。
PHP(全称:PHP: Hypertext Preprocessor)是一种广泛应用于Web开发的开源脚本语言,以其易学易用、高效灵活的特性深受广大开发者喜爱。诞生于1995年,由Rasmus Lerdorf创建,PHP最初用于简单的网页动态处理,如今已发展成为一款功能齐全、生态丰富的全栈开发工具,支持从网站前端交互到后端业务逻辑、数据库操作乃至API接口开发的全方位需求。 PHP的一大特点在于其与HTML的深度融合,可以直接嵌入到HTML文档中,通过特殊的起始标签“<?php”和结束标签“?>”界定PHP代码段。这种特性使得开发者能够轻松地在静态网页中插入动态内容,实现数据渲染、条件判断、循环处理等功能,极大地简化了Web开发流程。同时,PHP也支持纯脚本文件编写,适用于构建复杂的后台逻辑。 PHP语法简洁明了,借鉴了C、Perl等语言的特点,易于理解和学习,对于初学者友好。它支持面向过程、面向对象以及函数式编程范式,可根据项目需求和开发者喜好灵活选择。PHP内置丰富的数据类型(如整型、浮点型、字符串、数组、对象等),并提供了大量的预定义函数,涵盖了字符串操作、数学运算、文件系统处理、日期时间处理、数据库连接等常见功能,极大提高了开发效率。 在Web开发中,PHP与MySQL数据库的搭配尤为经典。PHP提供mysqli、PDO等数据库扩展,能够无缝连接MySQL,进行SQL查询、数据插入、更新、删除等操作,实现动态网站的数据持久化。此外,PHP还支持与其他数据库系统的连接,如PostgreSQL、SQLite、Oracle等,具有良好的数据库兼容性。 PHP拥有庞大的开发者社区和丰富的开源项目,如内容管理系统(CMS)WordPress、Drupal、Joomla,框架 Laravel、Symfony、CodeIgniter等,为开发者提供了丰富的代码资源和快速开发的便利。同时,官方维护的PHP文档详尽全面,社区活跃的技术论坛和问答网站为学习和解决问题提供了有力支持。 在性能优化方面,PHP支持 opcode 缓存(如APC、OpCache)以加速脚本执行,可通过配置调整、代码优化、使用缓存技术等手段提升应用性能。近年来,PHP持续进行性能改进与新特性的引入,如PHP 7系列版本在速度上有了显著提升,新增了类型声明、标量类型提示、null合并运算符等语法特性,进一步提升了开发效率和代码质量。 总的来说,PHP作为一种成熟的Web开发语言,凭借其易用性、灵活性、丰富的库与框架支持、强大的社区生态以及持续的性能优化,成为了构建各类动态网站、Web应用及API服务的理想选择。
Redis缓存是一种基于内存的高性能键值存储数据库。它常被用作缓存服务器,可以将常用的数据缓存在内存中,以提高应用程序的响应速度。 优点: 1. 快速读取:与传统的磁盘数据库相比,Redis缓存可以更快地读取数据。 2. 高并发:Redis缓存的单线程模型能够避免并发问题,同时支持高并发访问。 3. 数据结构丰富:Redis缓存支持多种数据结构,如字符串、哈希表、列表、集合、有序集合等,方便开发人员使用。 4. 分布式:Redis缓存可以实现分布式缓存,提高了系统的扩展性和容错性。 缺点: 1. 内存限制:Redis缓存存储的数据量受限于服务器的内存大小。 2. 数据一致性:Redis缓存中的数据可能会因为故障等原因丢失,需要进行备份和恢复操作。 3. 高并发写入:当Redis缓存中的数据需要频繁更新时,可能会导致性能下降。 Redis缓存支持多种数据结构,如字符串、哈希表、列表、集合、有序集合等。其中,字符串适用于缓存简单的值或对象,哈希表适用于缓存复杂对象,列表适用于缓存队列等数据结构,集合适用于缓存无序的元素集合,有序集合适用于缓存有序的元素集合。 Redis缓存的分布式实现可以通过一致性哈希算法等方式来实现。一致性哈希算法可以使得数据在多个节点之间均匀分布,提高系统的性能和可靠性。 为了保证Redis缓存的可靠性和数据一致性,可以使用持久化方式来将数据写入到磁盘中,以防止数据丢失。同时,可以设置主从复制,将数据复制到多个节点,提高系统的可靠性。 Redis缓存的过期策略有两种:定时过期和惰性过期。定时过期是指设置一个过期时间,在这个时间之后数据会被自动删除;惰性过期是指在访问数据时检查它是否过期,如果过期则进行删除。可以通过设置过期时间和过期策略来控制Redis缓存中数据的有效性。 Redis缓存的持久化方式有两种:RDB和AOF。RDB将内存中的数据周期性地写入到磁盘中,适用于需要快速备份和恢复数据的场景;AOF则将Redis缓存的写操作记录到文件中,适用于需要保证数据一致性和可靠性的场景。 为了优化Redis缓存的性能,可以采用以下方法: 1. 合理使用数据结构,选择适合的数据类型和算法。 2. 设置合理的过期时间和过期策略,避免数据的过期和无效。 3. 使用分布式缓存,将数据分散在多个节点中,提高系统的性能和可靠性。 4. 使用连接池和异步IO等技术,避免因连接和IO造成的性能瓶颈。 为了保证Redis缓存与数据库的一致性,可以使用缓存更新策略。当数据库中的数据发生变化时,可以通过订阅数据库更新事件的方式,将更新的数据同步到Redis缓存中,以保证数据的一致性。 为了实现Redis缓存的高可用性,可以使用主从复制和哨兵模式。主从复制可以将数据复制到多个节点,提高系统的容错性;哨兵模式则可以监控Redis缓存的状态,当主节点出现故障时,自动选择新的主节点,保证系统的高可用性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值