fastjson 泛型转换问题(详解)

系列文章目录

附属文章一:fastjson TypeReference 泛型类型(详解)


文章目录

  • 系列文章目录
  • 前言
  • 一、代码演示
    • 1. 不存在泛型转换
    • 2. 存在泛型转换
    • 3. 存在泛型集合转换
  • 二、原因分析
  • 三、解决方案
    • 1. 方案1:重新执行泛型的 json 转换
    • 2. 方案2:使用 TypeReference 指定泛型类型


前言

本文讲解使用 fastjson 进行 json 转换泛型 T、泛型集合 R<List>、或者子类中的泛型、或者多层泛型,存在的 json 转换异常报错问题,以及解决方案。


一、代码演示

data 实际对象类型:

@Data
public class SysUser {String userId;String userName;
}

1. 不存在泛型转换

响应类:

@Data
public class R {Integer code;String msg;SysUser data;
}

测试类:


@Slf4j
public class Test {public static void main(String[] args) {String jsonStr = "{\"code\":0,\"msg\":\"操作成功\",\"data\":{\"userId\":\"1001\",\"userName\":\"小白\"}}";R rSysUser = JSONObject.parseObject(jsonStr, R.class);SysUser sysUser = rSysUser.getData();log.info("sysUser={}", sysUser.toString());}
}

执行上述代码,结果如下:

在这里插入图片描述

通过断点调试可以看到 JSONObject.parseObject(jsonStr, R.class) 转换后的对象中的子对象的实际类型为 SysUser,数据为等值的形式。

2. 存在泛型转换

泛型响应类:

@Data
public class R<T> {Integer code;String msg;T data;
}

泛型测试类:


@Slf4j
public class Test {public static void main(String[] args) {String jsonStr = "{\"code\":0,\"msg\":\"操作成功\",\"data\":{\"userId\":\"1001\",\"userName\":\"小白\"}}";R<SysUser> rSysUser = JSONObject.parseObject(jsonStr, R.class);SysUser sysUser = rSysUser.getData();log.info("sysUser={}", sysUser.toString());}
}

执行上述代码,结果如下:

在这里插入图片描述

通过断点调试可以看到 JSONObject.parseObject(jsonStr, R.class) 转换后的对象中的子泛型对象的实际类型为 JSONObject,数据为 key-value 的形式。

此时往下执行,进行 JSONObject 和 SysUser 对象的直接赋值,就会抛出异常:

在这里插入图片描述

3. 存在泛型集合转换

泛型集合测试类:


@Slf4j
public class Test {public static void main(String[] args) {String jsonStr = "{\"code\":0,\"msg\":\"操作成功\",\"data\":[{\"userId\":\"1001\",\"userName\":\"小白\"}]}";R<List<SysUser>> rSysUser = JSONObject.parseObject(jsonStr, R.class);List<SysUser> sysUserList = rSysUser.getData();log.info("sysUserList={}", sysUserList.toString());SysUser sysUser = sysUserList.get(0);log.info("sysUser={}", sysUser.toString());}
}

执行上述代码,结果如下:
在这里插入图片描述
通过断点调试可以看到 JSONObject.parseObject(jsonStr, R.class) 转换后的对象中的泛型集合对象的实际类型为 JSONObject,数据为 key-value 的形式。

此时往下执行,进行 JSONObject 和 SysUser 对象的直接赋值,就会抛出异常:
在这里插入图片描述

扩展:

当然,泛型 T、泛型集合 R<List>、或者子类中的泛型、或者多层泛型,都存在同样的问题。本文不再演示。

二、原因分析

因为当 json 转换的对象是泛型时,我们无法获取到实际的类,无法获取到类的变量,也无法获取到类变量的 get、set 方法,所以我们无法将这个 json 数据转换到某一个实际的类对象中存储,所以 com.alibaba.fastjson 会临时转换为 JSONObject 对象,以 key-value 形式存储。

这样就存在一个问题,当我们将该泛型对象赋值转换为实际的类对象时,就会因类型不匹配而抛出异常。

三、解决方案

1. 方案1:重新执行泛型的 json 转换

将泛型转换为 json 字符串后,重新进行类对象转换。

泛型转换:

R<SysUser> rSysUser = JSONObject.parseObject(jsonStr, R.class);
SysUser sysUser = JSONObject.parseObject(JSONObject.toJSONString(rSysUser.getData()), SysUser.class);

泛型集合转换:

R<List<SysUser>> rSysUser = JSONObject.parseObject(jsonStr, R.class);
List<SysUser> sysUserList = JSONObject.parseArray(JSONObject.toJSONString(rSysUser.getData()), SysUser.class);

2. 方案2:使用 TypeReference 指定泛型类型

使用 fastjson 的 TypeReference 来指定泛型类型。

在指定了 json 转换中泛型的实际类型后,就能获取到实际的类,获取到类的变量,获取到类变量的 get、set 方法,从而将泛型的 json 转换成实际的类对象。

本文不过多讲解 TypeReference 类,详细了解请转 《fastjson TypeReference 泛型类型(详解)》https://editor.csdn.net/md/?articleId=139363645

泛型转换:

R<SysUser> rSysUser = JSONObject.parseObject(jsonStr, new TypeReference<R<SysUser>>(){});
SysUser sysUser = rSysUser.getData();

泛型集合转换:

R<List<SysUser>> rSysUser = JSONObject.parseObject(jsonStr, new TypeReference<R<List<SysUser>>>(){});
List<SysUser> sysUserList = rSysUser.getData();

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/20523.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据可视化每周挑战——中国高校数据分析

最近要高考了&#xff0c;这里祝大家金榜题名&#xff0c;旗开得胜。 这是数据集&#xff0c;如果有需要的&#xff0c;可以私信我。 import pandas as pd import numpy as np import matplotlib.pyplot as plt from pyecharts.charts import Line from pyecharts.charts impo…

iPhone 语言编程:深入探索与无限可能

iPhone 语言编程&#xff1a;深入探索与无限可能 在数字化时代的浪潮中&#xff0c;iPhone 作为一款全球领先的智能手机&#xff0c;其语言编程的奥秘一直吸引着众多开发者与爱好者的目光。iPhone 的语言编程不仅关乎技术实现&#xff0c;更涉及到用户体验、创新应用等多个层面…

图像处理ASIC设计方法 笔记26 非均匀性校正SOC如何设计

在红外成像技术领域,非均匀性校正是一个至关重要的环节,它直接影响到成像系统的性能和目标检测识别的准确性。非均匀性是指红外焦平面阵列(IRFPA)中各个像元对同一辐射强度的响应不一致的现象,这种不一致性可能是由于制造过程中的缺陷、材料的不均匀性或者像元间的热电特性…

simCSE句子向量表示(1)-使用transformers API

SimCSE SimCSE: Simple Contrastive Learning of Sentence Embeddings. Gao, T., Yao, X., & Chen, D. (2021). SimCSE: Simple Contrastive Learning of Sentence Embeddings. arXiv preprint arXiv:2104.08821. 1、huggingface官网下载模型 官网手动下载&#xff1a;pri…

集合操作进阶:关于移除列表元素的那点事

介绍 日常开发中&#xff0c;难免会对集合中的元素进行移除操作&#xff0c;如果对这方面不熟悉的话&#xff0c;就可能遇到 ConcurrentModificationException&#xff0c;那么&#xff0c;如何优雅地进行元素删除&#xff1f;以及其它方式为什么不行&#xff1f; 数据初始化…

深度学习在工业检测中的应用:基于SAM模型的自动掩码生成

深度学习在工业检测中的应用:基于SAM模型的自动掩码生成 引言 在工业生产过程中,异常检测是一项关键任务。及时发现并处理异常可以有效提高产品质量和生产效率。然而,传统的人工检测方法效率低下,难以应对海量数据的处理需求。随着深度学习技术的发展,自动化检测系统逐渐…

国内类似ChatGPT的大模型应用有哪些?发展情况如何了

第一部分&#xff1a;几个容易混淆的概念 很多人&#xff0c;包括很多粉丝的科技博主&#xff0c;经常把ChatGPT和预训练大模型混为一谈&#xff0c;因此有必要先做一个澄清。预训练大语言模型属于预训练大模型的一类&#xff0c;而ChatGPT、文心一言又是预训练大语言模型的一个…

node基础-持续更新

node基础 1.node模块2.node环境搭建3.fs模块4.ES模块和CommonJS模块4.1 更改后缀名4.2 package.json配置支持es模块4.3 变量别名4.4 CommonJS模块 5.打造自己的脚手架工具5.1创建自定义全局指令5.2 使用commander处理--help参数5.3 处理自定义指令5.4 逻辑代码模块化拆分5.5 命…

iPad里的图片如何导出 iPad的照片如何管理

我们的设备中充满了各种重要的照片和视频&#xff0c;特别是iPad&#xff0c;作为苹果公司的一款强大的平板电脑&#xff0c;它不仅能够捕捉生活中的精彩瞬间&#xff0c;还可以存储和展示我们珍贵的回忆。然而&#xff0c;随着照片数量的不断增加&#xff0c;有效地管理和导出…

对boot项目拆分成cloud项目的笔记

引言&#xff1a;这里我用的是新版本的技术栈 spring-boot-starter-parent >3.2.5 mybatis-spring-boot-starter >3.0.3 mybatis-plus-boot-starter >3.5.5 spring-cloud-dependencies …

JVMの内存泄漏内存溢出案例分析

1、内存溢出 内存溢出指的是程序在申请内存时&#xff0c;没有足够的内存可供分配&#xff0c;导致无法满足程序的内存需求&#xff0c;常见的内存溢出情况包括堆内存溢出&#xff08;Heap Overflow&#xff09;和栈溢出&#xff08;Stack Overflow&#xff09;&#xff1a; …

基于Open3D的点云处理21-交互式可视化

1. 区域选择、裁剪 o3d.visualization.draw_geometries_with_editing([pcd])按两次’Y’以将几何与y轴的负方向对齐按’K’锁定屏幕并切换到选择模式拖动选择矩形或使用[ctrl+ 左键] 单击多边形选择按’C’ 获取选定的几何图形按’S’保存选择的几何图形按’F’ 切换到freevie…

AI去衣技术中的几何着色:揭秘数字时尚的魔法

在数字化时代&#xff0c;人工智能&#xff08;AI&#xff09;正以前所未有的速度改变我们的生活&#xff0c;从智能家居到自动驾驶汽车&#xff0c;再到个性化医疗。然而&#xff0c;AI的影响远不止于此。它正在重塑我们对艺术、设计和时尚的理解。特别是在数字时尚领域&#…

Unity打包Webgl端进行 全屏幕自适应

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一&#xff1a;修改 index.html二&#xff1a;将非移动端设备&#xff0c;canvas元素的宽度和高度会设置为100%。三&#xff1a;修改style.css总结 下载地址&#x…

用户友好型模块argparse

1.简介 argparse 是 Python 的一个模块&#xff0c;用于编写用户友好的命令行接口。其主要作用是处理命令行参数。它使得开发者能够轻松地为 Python 脚本或程序定义、解析和使用命令行参数。 是Python 标准库的一部分&#xff0c;因此无需安装额外的包即可使用&#xff0c;它是…

详解 QtAndroid::requestPermissionsSync

QtAndroid::requestPermissionsSync 是 Qt 框架中用于在 Android 平台上同步请求运行时权限的函数。这个函数在 Qt for Android 的某个更新中被引入&#xff0c;以更好地支持 Android 6.0&#xff08;API 级别 23&#xff09;及以上版本引入的动态权限管理系统。下面是对该函数…

Solidity学习-投票合约示例

以下的合约有一些复杂&#xff0c;但展示了很多Solidity的语言特性。它实现了一个投票合约。 当然&#xff0c;电子投票的主要问题是如何将投票权分配给正确的人员以及如何防止被操纵。 我们不会在这里解决所有的问题&#xff0c;但至少我们会展示如何进行委托投票&#xff0c;…

windows下搭建Avalonia开发环境生成跨平台安装包(linux x64 deb、linux arm64 deb)

一&#xff0c;试验环境 &#xff08;1&#xff09;&#xff0c;Windows 10 专业版 22H2 10.0.19045.4412 &#xff08;Windows Feature Experience Pack 1000.19056.1000.0&#xff09; &#xff08;2&#xff09;&#xff0c;visual studio 2022 &#xff08;3&#xff09;&a…

九天毕昇深度学习平台 | TensorBoard使用

TensorBoard&#xff1a;TensorFlow 的可视化工具包 1、 九天毕昇深度学习平台 如何使用Tensorboard&#xff1f; 在左侧文件浏览器中&#xff0c;进入目标路径&#xff08;如 log 文件所在文件夹&#xff09;&#xff0c;点击“”&#xff0c;在右侧“Launcher”页点击“Tens…