Jaskson精讲第7篇-类继承关系下的JSON序列化与反序列化JsonTypeInfo

Jackson是Spring Boot(SpringBoot)默认的JSON数据处理框架,但是其并不依赖于任何的Spring 库。有的小伙伴以为Jackson只能在Spring框架内使用,其实不是的,没有这种限制。它提供了很多的JSON数据处理方法、注解,也包括流式API、树模型、数据绑定,以及复杂数据类型转换等功能。它虽然简单易用,但绝对不是小玩具,更多的内容我会写成一个系列,5-10篇文章,请您继续关注我。
- 《序列化与反序列化核心用法-JSON框架Jackson精解第1篇》
- 《特殊数据格式处理-JSON框架Jackson精解第2篇》
- 《属性序列化自定义排序与字母表排序-JSON框架Jackson精解第3篇》
- 《@JacksonInject与@JsonAlias注解-JSON框架Jackson精解第4篇》
- 《@JsonCreator自定义反序列化函数-JSON框架Jackson精解第5篇》
- 《Jaskson精讲第6篇-自定义JsonSerialize与Deserialize实现数据类型转换》
本篇文章是系列文章的第7篇,主要是为大家介绍一下,在Java 类继承的情况下如何实现父类及子类的JSON序列化与反序列化。
一、继承关系对象构建
首先构建一个ClsShape类表示形状。
public class ClsShape {
}
构建一个ClsCircle 类表示圆形。并添加了一系列的lombok注解,Data表示提供get、set、toString、hashCode等方法;EqualsAndHashCode注解在有继承关系的字类中使用;AllArgsConstructor和NoArgsConstructor分别提供全参和无参构造方法。
@Data
@EqualsAndHashCode(callSuper = true)
@AllArgsConstructor
@NoArgsConstructor
public class ClsCircle extends ClsShape {
Integer radius; //弧度
}
构建一个长方形类ClsRectangle ,成员变量width宽度,height高度。
@Data
@EqualsAndHashCode(callSuper = true)
@AllArgsConstructor
@NoArgsConstructor
public class ClsRectangle extends ClsShape {
private Integer width;
private Integer height;
}
构建一个ClsView类,表示画面。画面中有很多的ClsShape形状,所以用一个List封装。
@Data
public class ClsView {
private List<ClsShape> shapes;
}
二、序列化与反序列化测试
基础的形状类及画面类写完之后,下面的代码是用来完成:对象到Json字符串的序列化过程,和Json字符串反序列化为Java对象的过程代码。
@Test
void testJSON2Object() throws IOException {
ClsRectangle rectangle = new ClsRectangle(7,9); //构建正方形对象
ClsCircle circle = new ClsCircle(8); //构建长方形对象
List<ClsShape> shapes = new ArrayList<>(); //List<多种形状>
shapes.add(circle);
shapes.add(rectangle);
ClsView view = new ClsView(); //将List放入画面View
view.setShapes(shapes);
ObjectMapper mapper = new ObjectMapper();
System.out.println("-- 序列化 --");
String jsonStr = mapper.writeValueAsString(view);
System.out.println(jsonStr);
System.out.println("-- 反序列化 --");
ClsView deserializeView = mapper.readValue(jsonStr, ClsView.class);
System.out.println(deserializeView);
}
大家看最终在控制台的输出结果如下:序列化的过程是正常的,但是反序列化的时候报错了。
-- 序列化 --
{"shapes":[{"radius":8},{"width":7,"height":9}]}
-- 反序列化 --
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "radius" (class com.example.demo.javabase.ClsShape), not marked as ignorable (0 known properties: ])
at [Source: (String)"{"shapes":[{"radius":8},{"width":7,"height":9}]}"; line: 1, column: 23] (through reference chain: com.example.demo.javabase.ClsView["shapes"]->java.util.ArrayList[0]->com.example.demo.javabase.ClsShape["radius"])
抛出异常的主要原因是我们用来接收反序列化的结果时,使用的是List<ClsShape>,Java程序并不明确的知道,这个ClsShape形状是圆形ClsCircle,还是正方形ClsRectangle。所以无法将字符串正确的反序列化为java对象。
三、@JsonTypeInfo注解加到父类定义上
为了解决上面的这种继承关系对象的反序列化出现的问题,jackson为我们提供了JsonTypeInfo注解,把它加在父类定义上面即可。
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS)
public class ClsShape {
}
在父类定义上面加上@JsonTypeInfo注解之后,序列化与反序列化的输出结果如下。
-- 序列化 --
{"shapes":[
{"@class":"com.example.demo.javabase.ClsCircle","radius":8},
{"@class":"com.example.demo.javabase.ClsRectangle","width":7,"height":9}
]}
-- 反序列化 --
ClsView(shapes=[ClsCircle(radius=8), ClsRectangle(width=7, height=9)])
值得注意的是在序列化之后的java字符串中,每个Json对象都包含了一个新的属性@class,这也是该对象在继承关系下能够反序列化为正确的java对象(@class的值的类对象)的关键所在。
四、@JsonTypeInfo注解加到包含父类的成员变量上面
@JsonTypeInfo注解不仅可以加在父类的定义上面,也可以加到包含父类的成员变量上面。序列化和反序列化的结果和第三小节中的内容是一样的。
@Data
public class ClsView {
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS)
private List<ClsShape> shapes;
}
欢迎关注我的博客,里面有很多精品合集
- 本文转载注明出处(必须带连接,不能只转文字):字母哥博客。
觉得对您有帮助的话,帮我点赞、分享!您的支持是我不竭的创作动力! 。另外,笔者最近一段时间输出了如下的精品内容,期待您的关注。
- 《手摸手教你学Spring Boot2.0》
- 《Spring Security-JWT-OAuth2一本通》
- 《实战前后端分离RBAC权限管理系统》
- 《实战SpringCloud微服务从青铜到王者》
- 《VUE深入浅出系列》
Jaskson精讲第7篇-类继承关系下的JSON序列化与反序列化JsonTypeInfo的更多相关文章
- Jaskson精讲第6篇-自定义JsonSerialize与Deserialize实现数据类型转换
Jackson是Spring Boot(SpringBoot)默认的JSON数据处理框架,但是其并不依赖于任何的Spring 库.有的小伙伴以为Jackson只能在Spring框架内使用,其实不是的, ...
- 转 Redis 总结精讲 看一篇成高手系统-4
转 Redis 总结精讲 看一篇成高手系统-4 2018年05月31日 09:00:05 hjm4702192 阅读数:125633 本文围绕以下几点进行阐述 1.为什么使用redis 2.使用r ...
- Programming In Scala笔记-第十一章、Scala中的类继承关系
本章主要从整体层面了解Scala中的类层级关系. 一.Scala的类层级 在Java中Object类是所有类的最终父类,其他所有类都直接或间接的继承了Object类.在Scala中所有类的最终父类为A ...
- Unity类继承关系 图
UnityEngine(命名空间) 其他命名空间 其他类 Object(类) 其他类(继承自Object) Component(类)(继承自Object) 其他类(继承自Component) Tran ...
- PythonI/O进阶学习笔记_4.自定义序列类(序列基类继承关系/可切片对象/推导式)
前言: 本文代码基于python3 Content: 1.python中的序列类分类 2. python序列中abc基类继承关系 3. 由list的extend等方法来看序列类的一些特定方法 4. l ...
- Idea查看接口或类继承关系
打开想要查看的接口或者类文件,使用快捷键CTRL+H调出Hierarchy窗口 比如,想要查看Exception的类继承关系,首先定位到这个文件,然后调出Hierarchy窗口. 该窗口上面的一排工具 ...
- C# Wpf Shape类继承关系
Path派生于Shape namespace System.Windows.Shapes { public sealed class Path : Shape { // Path 派生于Shape } ...
- 在net中json序列化与反序列化 面向对象六大原则 (第一篇) 一步一步带你了解linq to Object 10分钟浅谈泛型协变与逆变
在net中json序列化与反序列化 准备好饮料,我们一起来玩玩JSON,什么是Json:一种数据表示形式,JSON:JavaScript Object Notation对象表示法 Json语法规则 ...
- 继承关系下的this关键字
继承关系下的this关键字 在继承关系下,父类中的this关键字并不总是表示父类中的变量和方法.this关键字的四种用法如前文所述,列举如下. 1) this(paras…); 访问其他的构造方法 2 ...
随机推荐
- 如何在Linux上使用xargs命令
大家好,我是良许. 在使用 Linux 时,你是否遇到过需要将一些命令串在一起,但是其中一个命令不接受管道输入的情况呢?在这种情况下,我们就可以使用 xargs 命令.xargs 可以将一个命令的输出 ...
- ASP.NET Core3.1使用IdentityServer4中间件系列随笔(二):创建API项目,配置IdentityServer保护API资源
配套源码:https://gitee.com/jardeng/IdentitySolution 接上一篇<ASP.NET Core3.1使用IdentityServer4中间件系列随笔(一):搭 ...
- 【java学习笔记】LongAdder
目录 1.背景 2.LongAdder 3.Striped64内部结构 4.LongAdder的add方法解析 5.Striped64的longAccumulate方法解析 6.总结 LongAdde ...
- 都2020年了,还再问GET和POST的区别?【深度好文】
最近看了一些同学的面经,发现无论什么技术岗位,还是会问到 get 和 post 的区别,而搜索出来的答案并不能让我们装得一手好逼,那就让我们从 HTTP 报文的角度来撸一波,从而搞明白他们的区别. 一 ...
- 总结删除文件或文件夹的7种方法-JAVA IO基础总结第4篇
本文是Java IO总结系列篇的第4篇,前篇的访问地址如下: 总结java中创建并写文件的5种方式-JAVA IO基础总结第一篇 总结java从文件中读取数据的6种方法-JAVA IO基础总结第二篇 ...
- Android开发之ScrollView去掉右侧滚动条,gridview如何去掉外边框
android:scrollbars="none" android:listSelector="@null"
- Unity3d UGUI插件之TSTableView
TSTableView是Tacticsoft工作室开发的一款适用于UGUI的列表(Table)插件,设计灵感来源于iOS/Mac的UITableView,提供高复用.高性能的列表,其主要特点是: 采用 ...
- Vue中父组件使用子组件的emit事件,获取emit事件传出的值并添加父组件额外的参数进行操作
需求是这样的,需要输入这样一个列表的数据,可以手动添加行,每一行中客户编号跟客户姓名是自动关联的,就是说选取了客户姓名之后,客户编号是自动填充的,客户姓名是一个独立的组件,每一个下拉项都是一个大的对象 ...
- 小白也能弄懂的目标检测之YOLO系列 - 第一期
大家好,上期分享了电脑端几个免费无广告且实用的录屏软件,这期想给大家来讲解YOLO这个算法,从零基础学起,并最终学会YOLOV3的Pytorch实现,并学会自己制作数据集进行模型训练,然后用自己训练好 ...
- TP6.0 获取请求对象的五种方式
目录 1. 门面类 2. 依赖注入 3. 框架提供的基础控制器的 request 属性 4. request() 助手函数 5. app() 超级助手函数 think\Request.think\fa ...