【java基础】根据泛型动态构造jackson的TypeReference(json反序列化为带泛型的类的对象)
根据泛型动态构造jackson的TypeReference
- 引出问题
- 使用TypeReference反序列化的例子
- 根据泛型动态构造TypeReference
- 带泛型的类如何表示?
- 完成HttpClient的实现
引出问题
- 将json字符串反序列化为带泛型的类的对象怎么操作?
- 怎么根据
TypeReference<List<People>>对象动态构造TypeReference<Result<List<People>>>对象
使用TypeReference反序列化的例子
有以下类定义:
class Result<T> {private long code;private T data;
}class People {private String name;
}
实例化以下对象:
Result<List<People>> result = new Result<>();
List<People> peopleList = new ArrayList<>();
People xiaoHong = new People("小红");
People xiaoMing = new People("小明");
peopleList.add(xiaoHong);
peopleList.add(xiaoMing);
result.setData(peopleList);
其对应的JSON字符串为:
{"code":0,"data":[{"name":"小红"},{"name":"小明"}]}
下面使用jackson的TypeReference来反序列化字符串为以上的对象:
String jsonStr = "{\"code\":0,\"data\":[{\"name\":\"小红\"},{\"name\":\"小明\"}]}";
TypeReference<Result<List<People>>> typeReference = new TypeReference<Result<List<People>>>() {};
ObjectMapper objectMapper = new ObjectMapper();
Result<List<People>> listResult = objectMapper.readValue(jsonStr, typeReference);
当我们构造http客户端的时候,有时候不想让用户看到类似Result<List<People>>这样的返回,只想给用户List<People>这样的数据,那怎么动态构造TypeReference呢?
根据泛型动态构造TypeReference
假设我们提供了一个http客户端工具,它的定义是这样的。
class HttpClient {public <T> T get(String url, Map<String,Object> params, TypeReference<T> typeR) {//获取jsonStr, 假设这里获取到的是:{"code":0,"data":[{"name":"小红"},{"name":"小明"}]}String jsonStr = execute(url, params);//todo 解析为枚举类型,下面会讲解如何实现}
}
假设我们这样调用HttpClient:
HttpClient client = new HttpClient();
//注意这里的TypeReference的泛型
List<People> result = client.get("http://xxxx", params, new TypeReference<List<People>>());
额额额???为啥不是TypeReference<Result<List<People>>> ???
这就是我们要达到的目的,即用户不关注外层包裹的Result,只需要指定实际想要的类型即可。下面我们来看下如何实现。
带泛型的类如何表示?
首先我们实现一个ParameterizedType的子类,至于这个类的作用请往下看:
import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;public class ParameterizedTypeImpl implements ParameterizedType, Serializable {private final Type[] actualTypeArguments;private final Type ownerType;private final Type rawType;public ParameterizedTypeImpl(Type[] actualTypeArguments, Type ownerType, Type rawType) {this.actualTypeArguments = actualTypeArguments;this.ownerType = ownerType;this.rawType = rawType;}@Overridepublic Type[] getActualTypeArguments() {return this.actualTypeArguments;}@Overridepublic Type getRawType() {return this.rawType;}@Overridepublic Type getOwnerType() {return this.ownerType;}
}
我们来解释一下这个类,先看一下这个类的继承链:
ParameterizedTypeImpl implements ParameterizedType extends Type
- Type接口的语义是指:类型,标识java里的所有类。(注意:Class类也是Type的实现类,下面会用到)
- ParameterizedType接口的语义是:带泛型的类。
在java9之前jdk是包含了ParameterizedTypeImpl的实现的,但在jdk9及以后就没了,所以保险起见我们自己需要实现一下。
我们再看一下TypeReference的定义:
public abstract class TypeReference<T> implements Comparable<TypeReference<T>> {protected final Type _type;protected TypeReference() {Type superClass = this.getClass().getGenericSuperclass();if (superClass instanceof Class) {throw new IllegalArgumentException("Internal error: TypeReference constructed without actual type information");} else {this._type = ((ParameterizedType)superClass).getActualTypeArguments()[0];}}public Type getType() {return this._type;}public int compareTo(TypeReference<T> o) {return 0;}
}
这里的_type成员变量即ParameterizedTypeImpl类型。
我们继续看ParameterizedTypeImpl几个成员变量的意思:(此处以:new TypeReference<Result<List<People>>>为例)
- rawType
此处的rowType=Result.class,即原始的类是什么 - actualTypeArguments
此处的actualTypeArguments=new Type[]{List<People>.class},为什么是数组类型,是因为泛型里面可以放多个类型,我可以这么放:Result<List<People>,Set<People>>,那么这里的actualTypeArguments=new Type[]{List<People>.class,Set<People.class>},因为是一个Type数组,而每个Type又是一个ParameterizedType,所以可以向下继续查看(嵌套)。 - ownerType
所谓的ownerType只在嵌套类中会出现,其他情况为空。举个例子:I<T>.S<E>,则S<E>的ownerType=I<T>
完成HttpClient的实现
class HttpClient {public <T> T get(String url, Map<String,Object> params, TypeReference<T> typeR) {//获取jsonStr, 假设这里获取到的是:{"code":0,"data":[{"name":"小红"},{"name":"小明"}]}String jsonStr = execute(url, params);ObjectMapper objectMapper = new ObjectMapper();//在此处偷梁换柱TypeReference<Result<T>> resultType = new TypeReference<Result<T>>>() {@Overridepublic Type getType() {//在外层再包一层Result,就是所谓的动态构造,是不是很简单!!!return new ParameterizedTypeImpl(new Type[]{typeR.getType()},null, Result.class);}};Result<T> listResult = objectMapper.readValue(jsonStr, resultType);//此处省略了一下异常判断,不可直接这么使用return listResult.getData();}
}
然后我们就可以这么调用了:
HttpClient client = new HttpClient();
//注意这里的TypeReference的泛型
List<People> result = client.get("http://xxxx", params, new TypeReference<List<People>>());
OK,完结!
相关文章:
【java基础】根据泛型动态构造jackson的TypeReference(json反序列化为带泛型的类的对象)
根据泛型动态构造jackson的TypeReference引出问题使用TypeReference反序列化的例子根据泛型动态构造TypeReference带泛型的类如何表示?完成HttpClient的实现引出问题 将json字符串反序列化为带泛型的类的对象怎么操作?怎么根据TypeReference<List<…...
为什么VMware会给我多创建了两个网络呢?Windows和Linux为什么可以彼此ping的通呢
为什么VMware会给我多创建了两个网络呢?Windows和Linux为什么可以彼此ping的通呢 文章目录为什么VMware会给我多创建了两个网络呢?Windows和Linux为什么可以彼此ping的通呢桥接模式ANT模式(VMnet8)仅主机模式(VMnet1&a…...
服务器带宽承载多少人同时访问计算方法-浏览器中查看当前网页所有资源数据大小-客服系统高并发承载人数【唯一客服】...
浏览器中怎么查看当前网页所有资源的数据大小 在开发者工具的“网络”选项卡中,可以看到所有请求和响应的详细信息,包括每个资源的大小。如果需要查看网页所有资源的总大小,可以按照以下步骤操作: 打开要查看的网页。打开开发者工…...
给新手----编译VSOMEIP保姆级别教程
前言:当你学习了SOMEIP理论基础后,一定很希望上手实操一波吧,本文档以SOMEIP协议里比较成熟的VSOMEIP开源框架为例,带你从0到1实现开源框架的下载到上手,坐稳啦,开车!!!&…...
MarkDown设置上下标
上标:$a^{2-5}$ 下标:$a_{n-1}$显示:结果 上标:a2−5a^{2-5}a2−5 下标:an−1a_{n-1}an−1 如果上下标中需要多个显示,需要用{}括起来,否则就像下面一样 上标:$a^2-5$ 下标&…...
Python批量爬取游戏卡牌信息
文章目录前言一、需求二、分析三、处理四、运行结果前言 本系列文章来源于真实的需求本系列文章你来提我来做本系列文章仅供学习参考阅读人群:有Python基础、Scrapy框架基础 一、需求 全站爬取游戏卡牌信息 二、分析 查看网页源代码,图片资源是否存在…...
什么是PCB走线的3W原则
在设计PCB的时候我们会经常说到3W原则, 它指的是两个PCB走线它们的中心间距不小于3倍线宽,这个W就是PCB走线的宽度。这样做的目的主要是为了减小走线1和走线2之间的串扰,一般对于时钟信号,复位信号等一些关键信号需要遵循3W原则。…...
计算机网络面试总结
计算机网络 1.计算机网络 2.计算机网络拓扑结构 3.计算机网络覆盖 4.时延 5.交换技术 6.单工、半双工、全双工 7.OSI模型 8.TCP/IP模型 9.物理层有哪些设备 10.数据链路层介质访问控制 11.数据链路层有哪些设备 12.数据链路层流量控制 13.数据链路层的三个基本问题和解决方法 1…...
VsCode SSH远程连接服务器【内网穿透公网连接】
文章目录1.前言2.VS code的安装和设置2.1 VS code的下载安装2.2 OpenSSH的启用2.3 为VS code配置ssh2.4 局域网内测试VS code的ssh连接2.5 Cpolar下载安装3.Cpolar端口设置3.1 Cpolar云端设置3.2 Cpolar本地设置4.公网访问测试5.结语1.前言 记得笔者小时候看电视,看…...
十八、动画与canvas
1.RequestAnimationFrame 早期定时动画 setTimeout和setInterval不能保证时间精度,第二个参数只能保证何时将代码添加到浏览器的任务队列 requestAnimationFrame(cb)的cb在浏览器重绘屏幕前调用 function updateProgress(){const div document.getElementById(d…...
自动化测试学习-Day4-selenium的安装和8种定位方法
哈喽,大家好! 本人21年毕业,软件工程专业,毕业后一直从事金融行业的软件测试。 希望大家一起见证一名卑微测试的成长之路。 目录 一、环境准备 1.浏览器下载 2.浏览器驱动下载 3.下载selenium 二、Selenium定位元素的8种方法…...
【Kubernetes】第二十五篇 - 布署 nodejs 后端项目(下)
一,前言 上一篇,介绍了部署后端项目之前,需要的准备的相关配置信息; 本篇,创建 Deployment、Service 完成后端项目布署; 二,解决 jenkins 安全问题 构建 docker 镜像之后,登录 do…...
贪心算法之区间问题总结
一、跳跃游戏跳跃游戏类的问题,不关心每一步怎么跳,只需要关心最大覆盖范围这里注意i是在当前最大可覆盖范围内遍历,如{2,1,0,1},就是在0~2范围内遍历,千万不能0~numsSize-1范围内遍历!!&#x…...
无线WiFi安全渗透与攻防(七)之WIFI07-WEP-wifite自动化渗透WEP加密
WIFI07-WEP-wifite自动化渗透WEP加密 1.wifite介绍 wifite是一款自动化wep、wpa以及wps破解工具,不支持windows和osx。wifite的特点是可以同时攻击多个采用wep和wpa加密的网络。wifite只需简单的配置即可自动化运行,期间无需人工干预。 目前支持任何li…...
震撼,支持多模态模型的ChatGPT 4.0发布了
最近几个月,互联网和科技圈几乎ChatGPT刷屏了,各种关于ChatGPT的概念和应用的帖子也是围绕在周围。当去年年底ChatGPT发布的那几天,ChatGPT确实震撼到了所有人,原来AI还可以这么玩,并且对国内的那些所谓的人工智能公司…...
IDEA常用插件列表
一 背景 IDEA常用插件列表,用来提供工作效率。你都安装了吗 IntelliJ IDEA 默认安装并提供了非常多的工具,比如 Maven Integration、Markdown support、SSH Remote Run 等。其中有很多好用,但是不为人知的工具。 二 插件列表 阿里代码规约…...
比df更好用的命令!
大家好,我是良许。 对于分析磁盘使用情况,有两个非常好用的命令:du 和 df 。简单来说,这两个命令的作用是这样的: du 命令:它是英文单词 disk usage 的简写,主要用于查看文件与目录占用多少磁…...
【Git使用学习】记录学习过程(1)
安装就省略了,安装结果如下。 Git Bash:这是一个模拟Linux环境的命令行工具,可以使用Git的所有功能。Git GUI:这是一个图形化界面的工具,可以方便地执行Git的常用操作。Git CMD:这是一个Windows命令行工具&…...
K_A18_001 基于STM32等单片机采集MQ2传感参数串口与OLED0.96双显示
K_A18_001 基于STM32等单片机采集MQ2传感参数串口与OLED0.96双显示一、资源说明二、基本参数参数引脚说明三、驱动说明IIC地址/采集通道选择/时序对应程序:四、部分代码说明1、接线引脚定义1.1、STC89C52RCMQ2传感参模块1.2、STM32F103C8T6MQ2传感参模块五、基础知识学习与相关…...
【云原生·Docker】常用命令
目录 🍁1、管理命令 🍁2、帮助命令 🍁3、镜像命令 🍁4、容器命令 🍂4.1.查看容器 🍂4.2.创建容器 🍂4.3.删除容器 🍂4.4.拷贝文件 🍂4.5.查看容器IP 🍁5、部署…...
避坑指南:Flink CDC监听Oracle时,LogMiner查不到数据导致任务挂掉的排查与修复
Flink CDC监听Oracle数据变更的深度避坑指南:LogMiner查询失效与性能优化实战 引言:当数据流突然中断时 凌晨三点,监控系统突然报警——Flink CDC任务持续运行两周后突然停止向Kafka推送数据变更。查看日志发现大量"ORA-00308: cannot o…...
别再只盯着H∞了!用MATLAB的musyn命令搞定µ综合,为你的不确定系统设计鲁棒控制器
用MATLAB的musyn命令实现综合:工程师的不确定系统鲁棒控制实战指南 在无人机飞控系统调试现场,工程师小王盯着屏幕上剧烈震荡的响应曲线皱起了眉头——明明在实验室仿真中表现完美的H∞控制器,在实际飞行测试中却频频出现不稳定现象。这种场景…...
如何高效完成从SVN到Git的完整迁移:svn2git实战指南
如何高效完成从SVN到Git的完整迁移:svn2git实战指南 【免费下载链接】svn2git 项目地址: https://gitcode.com/gh_mirrors/sv/svn2git 在软件开发生命周期中,版本控制系统迁移是一个关键但充满挑战的任务。随着Git在分布式版本控制领域的统治地位…...
别再手动转HTML了!用Towxml 3.0 + uni-app,5分钟搞定小程序Markdown渲染
5分钟解锁uni-app小程序Markdown渲染:Towxml 3.0全流程实战指南 每次在小程序里展示技术文档或博客内容时,你是否还在为Markdown转换头疼?手动处理表格嵌套、代码高亮、数学公式简直像在解谜。现在,用Towxml 3.0uni-app组合拳&…...
惊艳效果可视化:像素幻梦生成过程中间帧扩散去噪动态图解
惊艳效果可视化:像素幻梦生成过程中间帧扩散去噪动态图解 1. 像素幻梦创意工坊概览 Pixel Dream Workshop(像素幻梦创意工坊)是基于FLUX.1-dev扩散模型构建的新一代像素艺术生成工具。与传统AI绘图工具不同,它采用了明亮的16-bi…...
NVIDIA Profile Inspector:3个颠覆性技巧解锁显卡隐藏性能
NVIDIA Profile Inspector:3个颠覆性技巧解锁显卡隐藏性能 【免费下载链接】nvidiaProfileInspector 项目地址: https://gitcode.com/gh_mirrors/nv/nvidiaProfileInspector 我们都有过这样的经历:明明显卡配置不差,游戏却总是卡顿、…...
开箱即用!春联生成模型-中文-base快速体验:1秒出对联,效果超预期
开箱即用!春联生成模型-中文-base快速体验:1秒出对联,效果超预期 1. 前言:AI写春联的时代来了 春节贴春联是中国人延续千年的传统习俗,但创作一副对仗工整、寓意吉祥的春联并不容易。现在,借助AI技术&…...
高效整合3300+品牌图标:Simple Icons全场景应用指南
高效整合3300品牌图标:Simple Icons全场景应用指南 【免费下载链接】simple-icons SVG icons for popular brands 项目地址: https://gitcode.com/GitHub_Trending/si/simple-icons 你是否曾在设计项目中花费数小时寻找合适的品牌图标?从打开浏览…...
DataMatrix 基准测试结果有偏差:Dynamsoft 检测到的代码比 Scandit 多 51%
DataMatrix 基准测试结果有偏差:Dynamsoft 检测到的代码比 Scandit 多 51%。 这是我们SDK基准测试系列的第二部分。第一部分比较了Dynamsoft和Scandit在旋转条形码上的性能,Dynamsoft的准确率最高提升了12.9%。第二部分将着重解决一个更复杂的问题&#…...
2026年3月大模型全景深度解析:国产登顶、百万上下文落地、Agent工业化,AI实用时代全面来临[特殊字符]
🔥个人主页:北极的代码(欢迎来访) 🎬作者简介:java后端学习者 ❄️个人专栏:苍穹外卖日记,SSM框架深入,JavaWeb ✨命运的结局尽可永在,不屈的挑战却不可须臾或…...
