Redis获取数据转json,解决动态泛型传参

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: 项目有两种角色需要不同的登录权限,将redis做为用户登录信息缓存数据库。码一个方法,希望能够根据传入不用用户实体类型来获取相应的数据。用户实体为:SessionEntity<User1>、SessionEntity<User2>。json使用FastJson。

 场景:项目有两种角色需要不同的登录权限,将redis做为用户登录信息缓存数据库。码一个方法,希望能够根据传入不用用户实体类型来获取相应的数据。用户实体为:SessionEntity<User1>、SessionEntity<User2>。json使用FastJson。

先阐述遇到的几个问题:

1、redis获取到的数据序列化后,转json,经常提示转换异常(并不是每次,只是时常)。

2、不想每种用户都书写一个redis操作方法(显得tai low)。

解决:

1、redis获取到的数据序列化后,转json,经常提示转换异常:

   先说redis有两种获取方式。

1)

redisTemplate.opsForValue().get(key);

image.gif

2)

SessionEntity result = redisTemplate.execute(new RedisCallback<SessionEntity>() {
            public SessionEntity doInRedis(RedisConnection connection)
                    throws DataAccessException {
                RedisSerializer<String> serializer = getRedisSerializer();
                byte[] key = serializer.serialize(s);
                byte[] value = connection.get(key);
                if (value == null) {
                    return null;
                }
                String json = serializer.deserialize(value);
                return JSONObject.parseObject(json,SessionEntity.class);
            }
        });

image.gif

显然第一种的方式比较简单。查看源码,发现第一种方式底层调用的也是redisTemplate.execute方法,所以应该算是一种封装吧。我们一直采用的是第二种方式。(第一种方式试过,也一样会出现json强转异常)。这里出现过json异常,怀疑是跟泛型有关。这里手动指定泛型反序列化类型。

修改后:

SessionEntity result = redisTemplate.execute(new RedisCallback<SessionEntity>() {
            public SessionEntity doInRedis(RedisConnection connection)
                    throws DataAccessException {
                RedisSerializer<String> serializer = getRedisSerializer();
                byte[] key = serializer.serialize(s);
                byte[] value = connection.get(key);
                if (value == null) {
                    return null;
                }
                String json = serializer.deserialize(value);
                return JSONObject.parseObject(json, new TypeReference<SessionEntity<User>>(){});
            }
        });

image.gif

完美~,确实解决了json强转异常。

那么问题来了,这里的TypeReference需要手动指定明确的的实体类型,尝试添加泛型:

SessionEntity<T> result = redisTemplate.execute(new RedisCallback<SessionEntity<T>>() {
            public SessionEntity<T> doInRedis(RedisConnection connection)
                    throws DataAccessException {
                RedisSerializer<String> serializer = getRedisSerializer();
                byte[] key = serializer.serialize(s);
                byte[] value = connection.get(key);
                if (value == null) {
                    return null;
                }
                String json = serializer.deserialize(value);
                return JSONObject.parseObject(json, new TypeReference<SessionEntity<T>>(){});
            }
        });

image.gif

看样子是没什么问题,而且泛型也被识别到了。 但是依旧无法通过。

2、不想每种用户都书写一个redis操作方法:

上面说到就算加了泛型也依旧无法通过,尝试了多种方式依旧如此。百度了一圈,都是说使用TypeReference这个来解决,但是并没有提及动态泛型的问题。偶然间看到文章说Fastjson不支持,所以尝试替换成jackson。

替换后的代码:

SessionEntity<T> result = redisTemplate.execute(new RedisCallback<SessionEntity<T>>() {
            public SessionEntity<T> doInRedis(RedisConnection connection)
                    throws DataAccessException {
                RedisSerializer<String> serializer = getRedisSerializer();
                byte[] key = serializer.serialize(s);
                byte[] value = connection.get(key);
                if (value == null) {
                    return null;
                }
                String json = serializer.deserialize(value);
                ObjectMapper om = new ObjectMapper();
                JavaType javatype = om.getTypeFactory().constructParametricType(SessionEntity.class, clazz);
                try {
                    return om.readValue(json, javatype);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                return null;
//                return JSONObject.parseObject(json, new TypeReference<SessionEntity<T>>(){});
            }
        });

image.gif

这里使用到了jackson的ObjectMapper。ObjectMapper类是Jackson库的主要类。它提供一些功能将转换成Java对象匹配JSON结构,反之亦然。它使用JsonParser和JsonGenerator的实例实现JSON实际的读/写。(复制来的)发现问题解决。

提供的抽象方法为:

public <T> SessionEntity<T> get(final String s, Class<T> clazz);

调用方式为:

sessionEntityDao.get(key, User1.class); 跟 sessionEntityDao.get(key, User2.class);

由于这里使用到的是jackson-databind-2.6.0的库,这个版本种constructParametricType这个方法已经快要过时,更高版本使用

constructParametrizedType

替换。这里我还没尝试过,等有空再玩。

这里问题已经解决,纯粹做个笔记以供自己以后方便查阅。这里只提供自己项目中遇到的解决方式之一,相信应该还有其他方式可以解决。如果有说明错误的地方,请指出并见谅。


相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
13天前
|
数据采集 JSON 测试技术
如何在Python中高效实现CSV到JSON的数据转换
在实际项目中,数据格式转换是常见问题,尤其从CSV到JSON的转换。本文深入探讨了多种转换方法,涵盖Python基础实现、数据预处理、错误处理、性能优化及调试验证技巧。通过分块处理、并行处理等手段提升大文件转换效率,并介绍如何封装为命令行工具或Web API,实现自动化批量处理。关键点包括基础实现、数据清洗、异常捕获、性能优化和单元测试,确保转换流程稳定高效。
128 83
|
4月前
|
NoSQL Redis
Redis的数据淘汰策略有哪些 ?
Redis 提供了 8 种数据淘汰策略,分为淘汰易失数据和淘汰全库数据两大类。易失数据淘汰策略包括:volatile-lru、volatile-lfu、volatile-ttl 和 volatile-random;全库数据淘汰策略包括:allkeys-lru、allkeys-lfu 和 allkeys-random。此外,还有 no-eviction 策略,禁止驱逐数据,当内存不足时新写入操作会报错。
408 16
|
4天前
|
缓存 NoSQL 关系型数据库
Redis应用—1.在用户数据里的应用
本文主要介绍了社区电商的业务闭环及Redis缓存架构中遇到的典型生产问题及其解决方案。通过介绍的设计和优化,社区电商平台能够在高并发读取和少量写入的情况下,保持高性能和数据一致性。
Redis应用—1.在用户数据里的应用
|
2月前
|
JSON 前端开发 搜索推荐
关于商品详情 API 接口 JSON 格式返回数据解析的示例
本文介绍商品详情API接口返回的JSON数据解析。最外层为`product`对象,包含商品基本信息(如id、name、price)、分类信息(category)、图片(images)、属性(attributes)、用户评价(reviews)、库存(stock)和卖家信息(seller)。每个字段详细描述了商品的不同方面,帮助开发者准确提取和展示数据。具体结构和字段含义需结合实际业务需求和API文档理解。
|
5天前
|
JSON JavaScript 前端开发
处理从API返回的JSON数据时返回Unicode编码字符串怎么处理
在处理API返回的JSON数据时,遇到类似`\u7f51\u7edc\u8fde\u63a5\u9519\u8bef`的Unicode编码字符串,可使用JavaScript内置方法转换为可读文字。主要方法包括:1. 使用`JSON.parse`自动解析;2. 使用`decodeURIComponent`和`escape`组合解码;3. 在API调用中直接处理响应数据。这些方法能有效处理多语言内容,确保正确显示非ASCII字符。
|
10天前
|
JSON API 数据格式
淘宝商品评论数据API接口详解及JSON示例返回
淘宝商品评论数据API接口是淘宝开放平台提供的一项服务,旨在帮助开发者通过编程方式获取淘宝商品的评论数据。这些数据包括评论内容、评论时间、评论者信息、评分等,对于电商分析、用户行为研究、竞品分析等领域都具有极高的价值。
|
2月前
|
JSON 缓存 API
解析电商商品详情API接口系列,json数据示例参考
电商商品详情API接口是电商平台的重要组成部分,提供了商品的详细信息,支持用户进行商品浏览和购买决策。通过合理的API设计和优化,可以提升系统性能和用户体验。希望本文的解析和示例能够为开发者提供参考,帮助构建高效、可靠的电商系统。
53 12
|
3月前
|
缓存 NoSQL Redis
Redis经典问题:数据并发竞争
数据并发竞争是大流量系统(如火车票系统、微博平台)中常见的问题,可能导致用户体验下降甚至系统崩溃。本文介绍了两种解决方案:1) 加写回操作加互斥锁,查询失败快速返回默认值;2) 保持多个缓存备份,减少并发竞争概率。通过实践案例展示,成功提高了系统的稳定性和性能。
|
3月前
|
缓存 监控 NoSQL
Redis经典问题:数据不一致
在使用Redis时,缓存与数据库数据不一致会导致应用异常。主要原因包括缓存更新失败、Rehash异常等。解决方案有:重试机制、缩短缓存时间、优化写入策略、建立监控报警、定期验证一致性、采用缓存分层及数据回滚恢复机制。这些措施可确保数据最终一致性,提升应用稳定性和性能。
|
4月前
|
缓存 NoSQL 关系型数据库
Redis和Mysql如何保证数据⼀致?
在项目中,为了解决Redis与Mysql的数据一致性问题,我们采用了多种策略:对于低一致性要求的数据,不做特别处理;时效性数据通过设置缓存过期时间来减少不一致风险;高一致性但时效性要求不高的数据,利用MQ异步同步确保最终一致性;而对一致性和时效性都有高要求的数据,则采用分布式事务(如Seata TCC模式)来保障。
102 14