Jackson类层次结构中的一些应用(Inheritance with Jackson)
Have a look at working with class hierarchies in Jackson.
如何在Jackson中使用类层次结构。
Inclusion of Subtype Information
There are two ways to add type information when serializing and deserializing data objects, namely global default typing and per-class annotations.
Global Default Typing
@Data
@AllArgsConstructor
@NoArgsConstructor
public abstract class Vehicle {private String make;private String model;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Car extends Vehicle {private int seatingCapacity;private double topSpeed;public Car(String make, String model, int seatingCapacity, double topSpeed) {super(make, model);this.seatingCapacity = seatingCapacity;this.topSpeed = topSpeed;}
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Truck extends Vehicle {private double payloadCapacity;public Truck(String make, String model, double payloadCapacity) {super(make, model);this.payloadCapacity = payloadCapacity;}
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Fleet {private List<Vehicle> vehicles;
}
安全白名单
PolymorphicTypeValidator ptv = BasicPolymorphicTypeValidator.builder().allowIfSubType("javabasic.enumprac").allowIfSubType("java.util.ArrayList").build();ObjectMapper mapper = new ObjectMapper();
mapper.activateDefaultTyping(ptv, ObjectMapper.DefaultTyping.NON_FINAL);Car car = new Car("Mercedes-Benz", "S500", 5, 250.0);
Truck truck = new Truck("Isuzu", "NQR", 7500.0);
List<Vehicle> vehicles = new ArrayList<>();
vehicles.add(car);
vehicles.add(truck);
Fleet serializedFleet = new Fleet();
serializedFleet.setVehicles(vehicles);String jsonDataString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(serializedFleet);
System.out.println(jsonDataString);
[ "javabasic.enumprac.Fleet", {"vehicles" : [ "java.util.ArrayList", [ [ "javabasic.enumprac.Car", {"make" : "Mercedes-Benz","model" : "S500","seatingCapacity" : 5,"topSpeed" : 250.0} ], [ "javabasic.enumprac.Truck", {"make" : "Isuzu","model" : "NQR","payloadCapacity" : 7500.0} ] ] ]
} ]
String JSON= "[ \"javabasic.enumprac.Fleet\", {\n" +" \"vehicles\" : [ \"java.util.ArrayList\", [ [ \"javabasic.enumprac.Car\", {\n" +" \"make\" : \"Mercedes-Benz\",\n" +" \"model\" : \"S500\",\n" +" \"seatingCapacity\" : 5,\n" +" \"topSpeed\" : 250.0\n" +" } ], [ \"javabasic.enumprac.Truck\", {\n" +" \"make\" : \"Isuzu\",\n" +" \"model\" : \"NQR\",\n" +" \"payloadCapacity\" : 7500.0\n" +" } ] ] ]\n" +"} ]";Fleet deserializedFleet = mapper.readValue(JSON, Fleet.class);
System.out.println(deserializedFleet);
Fleet(vehicles=[Car(seatingCapacity=5, topSpeed=250.0), Truck(payloadCapacity=7500.0)])
Per-Class Annotations
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME,include = JsonTypeInfo.As.PROPERTY,property = "type")
@JsonSubTypes({@JsonSubTypes.Type(value = Car.class, name = "car"),@JsonSubTypes.Type(value = Truck.class, name = "truck")
})
@Data
@AllArgsConstructor
@NoArgsConstructor
public abstract class Vehicle {private String make;private String model;
}
其他model不变
Car car = new Car("Mercedes-Benz", "S500", 5, 250.0);
Truck truck = new Truck("Isuzu", "NQR", 7500.0);
List<Vehicle> vehicles = new ArrayList<>();
vehicles.add(car);
vehicles.add(truck);
Fleet serializedFleet = new Fleet();
serializedFleet.setVehicles(vehicles);
ObjectMapper mapper = new ObjectMapper();
String jsonDataString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(serializedFleet);
System.out.println(jsonDataString);
{"vehicles" : [ {"type" : "car","make" : "Mercedes-Benz","model" : "S500","seatingCapacity" : 5,"topSpeed" : 250.0}, {"type" : "truck","make" : "Isuzu","model" : "NQR","payloadCapacity" : 7500.0} ]
}
Fleet deserializedFleet = mapper.readValue(jsonDataString, Fleet.class);
System.out.println(deserializedFleet);
Fleet(vehicles=[Car(seatingCapacity=5, topSpeed=250.0), Truck(payloadCapacity=7500.0)])
Ignoring Properties from a Supertype
Sometimes, some properties inherited from superclasses need to be ignored during serialization or deserialization. This can be achieved by one of three methods: annotations, mix-ins and annotation introspection.
Annotations
有两种常用的Jackson注释来忽略属性,它们是@JsonIgnore和@JsonIgnoreProperties。
@JsonIgnore directly applied to type members.
@JsonIgnoreProperties applied to type and type member.
@JsonIgnoreProperties is more powerful
it can ignore properties inherited from supertypes that we do not have control of.
it can ignore many properties at once.
@Data
@AllArgsConstructor
@NoArgsConstructor
public abstract class Vehicle {private String make;private String model;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
@JsonIgnoreProperties({ "model", "seatingCapacity" })
public class Car extends Vehicle {private int seatingCapacity;@JsonIgnoreprivate double topSpeed;public Car(String make, String model, int seatingCapacity, double topSpeed) {super(make, model);this.seatingCapacity = seatingCapacity;this.topSpeed = topSpeed;}
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Crossover extends Car {private double towingCapacity;public Crossover(String make, String model, int seatingCapacity, double topSpeed, double towingCapacity) {super(make, model, seatingCapacity, topSpeed);this.towingCapacity = towingCapacity;}
}
@Data
@AllArgsConstructor
public class Sedan extends Car {public Sedan(String make, String model, int seatingCapacity, double topSpeed) {super(make, model, seatingCapacity, topSpeed);}
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Fleet {private List<Vehicle> vehicles;
}
Sedan sedan = new Sedan("Mercedes-Benz", "S500", 5, 250.0);
Crossover crossover = new Crossover("BMW", "X6", 5, 250.0, 6000.0);
List<Vehicle> vehicles = new ArrayList<>();
vehicles.add(sedan);
vehicles.add(crossover);ObjectMapper mapper = new ObjectMapper();
String jsonDataString = mapper.writeValueAsString(vehicles);System.out.println(jsonDataString);
[{"make":"Mercedes-Benz"},{"make":"BMW","towingCapacity":6000.0}]
Mix-ins
Mix-ins allow us to ignoring properties when serializing and deserializing without the need to directly apply annotations to a class.
This is especially useful when dealing with third-party classes
@Data
@AllArgsConstructor
@NoArgsConstructor
public abstract class Vehicle {private String make;private String model;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Car extends Vehicle {private int seatingCapacity;private double topSpeed;public Car(String make, String model, int seatingCapacity, double topSpeed) {super(make, model);this.seatingCapacity = seatingCapacity;this.topSpeed = topSpeed;}
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Crossover extends Car {private double towingCapacity;public Crossover(String make, String model, int seatingCapacity, double topSpeed, double towingCapacity) {super(make, model, seatingCapacity, topSpeed);this.towingCapacity = towingCapacity;}
}
@Data
@AllArgsConstructor
public class Sedan extends Car {public Sedan(String make, String model, int seatingCapacity, double topSpeed) {super(make, model, seatingCapacity, topSpeed);}
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Fleet {private List<Vehicle> vehicles;
}
public static void main(String[] args) throws JsonProcessingException {ObjectMapper mapper = new ObjectMapper();mapper.addMixIn(Car.class, CarMixIn.class);Sedan sedan = new Sedan("Mercedes-Benz", "S500", 5, 250.0);Crossover crossover = new Crossover("BMW", "X6", 5, 250.0, 6000.0);List<Vehicle> vehicles = new ArrayList<>();vehicles.add(sedan);vehicles.add(crossover);String jsonDataString = mapper.writeValueAsString(vehicles);System.out.println(jsonDataString);}private abstract class CarMixIn {@JsonIgnorepublic String make;@JsonIgnorepublic String topSpeed;}
原始值:
[{"make":"Mercedes-Benz","model":"S500","seatingCapacity":5,"topSpeed":250.0},{"make":"BMW","model":"X6","seatingCapacity":5,"topSpeed":250.0,"towingCapacity":6000.0}]ignore以后得值
[{"model":"S500","seatingCapacity":5},{"model":"X6","seatingCapacity":5,"towingCapacity":6000.0}]
Annotation Introspection
the most powerful method to ignore supertype properties since it allows for detailed customization using the AnnotationIntrospector.
class IgnoranceIntrospector extends JacksonAnnotationIntrospector {public boolean hasIgnoreMarker(AnnotatedMember m) {return m.getDeclaringClass() == Vehicle.class && m.getName() == "model"|| m.getDeclaringClass() == Car.class|| m.getName() == "towingCapacity"|| super.hasIgnoreMarker(m);}
}
Sedan sedan = new Sedan("Mercedes-Benz", "S500", 5, 250.0);
Crossover crossover = new Crossover("BMW", "X6", 5, 250.0, 6000.0);
List<Vehicle> vehicles = new ArrayList<>();
vehicles.add(sedan);
vehicles.add(crossover);ObjectMapper mapper = new ObjectMapper();
mapper.setAnnotationIntrospector(new IgnoranceIntrospector());
String jsonDataString = mapper.writeValueAsString(vehicles);
System.out.println(jsonDataString);
[{"make":"Mercedes-Benz"},{"make":"BMW"}]
Subtype Handling Scenarios
Conversion Between Subtypes
Jackson allows an object to be converted to aother type object.
it is most helpful when used between two subtypes of the same interface or class to secure values and functionality.
@Data
@AllArgsConstructor
@NoArgsConstructor
public abstract class Vehicle {private String make;private String model;
}
在Car和Truck的属性上添加@JsonIgnore注释以避免不兼容
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Car extends Vehicle {@JsonIgnoreprivate int seatingCapacity;@JsonIgnoreprivate double topSpeed;public Car(String make, String model, int seatingCapacity, double topSpeed) {super(make, model);this.seatingCapacity = seatingCapacity;this.topSpeed = topSpeed;}
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Truck extends Vehicle {@JsonIgnoreprivate double payloadCapacity;public Truck(String make, String model, double payloadCapacity) {super(make, model);this.payloadCapacity = payloadCapacity;}
}
Car car = new Car("Benz", "S500", 5, 250.0);
Truck truck1 = new Truck("Isuzu", "NQR", 7500.0);ObjectMapper mapper = new ObjectMapper();String s = mapper.writeValueAsString(car);
System.out.println(s);String s1 = mapper.writeValueAsString(truck1);
System.out.println(s1);Truck truck = mapper.convertValue(car, Truck.class);
System.out.println(truck);
{"make":"Benz","model":"S500"}
{"make":"Isuzu","model":"NQR"}
Truck(payloadCapacity=0.0)
Deserialization Without No-arg Constructors
默认情况下,Jackson通过使用无参数构造函数来重新创建数据对象。
By default, Jackson recreates data objects by using no-arg constructors.
In a class hierarchy where a no-arg constructor must be added to a class and all those higher in the inheritance chain. In these cases, creator methods come to the rescue.
Specifically, all no-arg constructors are dropped, and constructors of concrete subtypes are annotated with @JsonCreator and @JsonProperty to make them creator methods.
@Data
@AllArgsConstructor
@NoArgsConstructor
public abstract class Vehicle {private String make;private String model;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Car extends Vehicle {private int seatingCapacity;private double topSpeed;@JsonCreatorpublic Car(@JsonProperty("make") String make,@JsonProperty("model") String model,@JsonProperty("seating") int seatingCapacity,@JsonProperty("topSpeed") double topSpeed) {super(make, model);this.seatingCapacity = seatingCapacity;this.topSpeed = topSpeed;}
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Truck extends Vehicle {private double payloadCapacity;@JsonCreatorpublic Truck(@JsonProperty("make") String make,@JsonProperty("model") String model,@JsonProperty("payload") double payloadCapacity) {super(make, model);this.payloadCapacity = payloadCapacity;}
}
Car car = new Car("Mercedes-Benz", "S500", 5, 250.0);
Truck truck = new Truck("Isuzu", "NQR", 7500.0);
List<Vehicle> vehicles = new ArrayList<>();
vehicles.add(car);
vehicles.add(truck);
Fleet serializedFleet = new Fleet();
serializedFleet.setVehicles(vehicles);ObjectMapper mapper = new ObjectMapper();
mapper.enableDefaultTyping();
String jsonDataString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(serializedFleet);
System.out.println(jsonDataString);
Fleet fleet = mapper.readValue(jsonDataString, Fleet.class);
System.out.println(fleet);
{"vehicles" : [ "java.util.ArrayList", [ [ "javabasic.enumprac.prac.Car", {"make" : "Mercedes-Benz","model" : "S500","topSpeed" : 250.0,"seatingCapacity" : 5} ], [ "javabasic.enumprac.prac.Truck", {"make" : "Isuzu","model" : "NQR","payloadCapacity" : 7500.0} ] ] ]
}Fleet(vehicles=[Car(seatingCapacity=5, topSpeed=250.0), Truck(payloadCapacity=7500.0)])
-----------------------------------------------------------------------------读书笔记摘自 文章:Inheritance with Jackson
相关文章:
Jackson类层次结构中的一些应用(Inheritance with Jackson)
Have a look at working with class hierarchies in Jackson. 如何在Jackson中使用类层次结构。 Inclusion of Subtype Information There are two ways to add type information when serializing and deserializing data objects, namely global default typing and per-cl…...
Python求均值、方差、标准偏差SD、相对标准偏差RSD
均值 均值是统计学中最常用的统计量,用来表明资料中各观测值相对集中较多的中心位置。用于反映现象总体的一般水平,或分布的集中趋势。 import numpy as npa [2, 4, 6, 8]print(np.mean(a)) # 均值 print(np.average(a, weights[1, 2, 1, 1])) # 带…...
SQL ASNI where from group order 顺序
SQL语句执行顺序: from–>where–>group by -->having — >select --> order 第一步:from语句,选择要操作的表。 第二步:where语句,在from后的表中设置筛选条件,筛选出符合条件的记录。 …...
springboot(39) : RestTemplate完全体
HTTP请求调用集成,支持GET,POST,JSON,Header调用,日志打印,请求耗时计算,设置中文编码 1.使用(注入RestTemplateService) Autowiredprivate RestTemplateService restTemplateService; 2.RestTemplate配置类 import org.springframework.context.annotation.Bean; import org.…...
python中计算2的32次方减1,python怎么算2的3次方
大家好,给大家分享一下怎么样用python编写2的n次方,n由键盘输入,很多人还不知道这一点。下面详细解释一下。现在让我们来看看! ---恢复内容开始--- 1、内置函数:取绝对值函数abs() 2、内置函数:取最大值max()ÿ…...
阿里云SLB负载均衡ALB、CLB和NLB有什么区别?
阿里云负载均衡SLB分为传统型负载均衡CLB(原SLB)、应用型负载均衡ALB和网络型负载均衡NLB,三者有什么区别?CLB是之前的传统的SLB,基于物理机架构的4层负载均衡;ALB是应用型负载均衡,7层负载均衡…...
SynergyNet(头部姿态估计 Head Pose Estimation)复现 demo测试
目录 0 相关资料1 环境搭建2 安装 SynergyNet3 下载相关文件4 编译5 测试 0 相关资料 SynergyNet(github):https://github.com/choyingw/SynergyNet 1 环境搭建 我用的AutoDL平台搭建 选择镜像 PyTorch 1.9.0 Python 3.8(ubuntu18.04) Cu…...
mysql高级(尚硅谷-夏磊)
目录 内容介绍 Linux下MySQL的安装与使用 Mysql逻辑架构 Mysql存储引擎 Sql预热 索引简介 内容介绍 1、Linux下MySQL的安装与使用 2、逻辑架构 3、sql预热 Linux下MySQL的安装与使用 1、docker安装docker run -d \-p 3309:3306 \-v /atguigu/mysql/mysql8/conf:/etc/my…...
C++实用技术(二)std::function和bind绑定器
目录 简介std::functionstd::function对象包装器std::function做回调函数 std::bind绑定器bind绑定普通函数bind绑定成员函数 简介 C11新增了std::function和std::bind。用于函数的包装以及参数的绑定。可以替代一些函数指针,回调函数的场景。 std::function std…...
vue框架 element导航菜单el-submenu 简单使用方法--以侧边栏举例
1、目标 实现动态增删菜单栏的效果,所以要在数据库中建表 2 、建表 2.1、表样式 2.2、表数据 3、实体类 import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor;import java.util.List;Data AllArgsConstructor NoArgsConstr…...
Nodejs 第八章(npm搭建私服)
构建npm私服 构建私服有什么收益吗? 可以离线使用,你可以将npm私服部署到内网集群,这样离线也可以访问私有的包。提高包的安全性,使用私有的npm仓库可以更好的管理你的包,避免在使用公共的npm包的时候出现漏洞。提高…...
React Native获取手机屏幕宽高(Dimensions)
import { Dimensions } from react-nativeconsole.log(Dimensions, Dimensions.get(window)) 参考链接: https://www.reactnative.cn/docs/next/dimensions#%E6%96%B9%E6%B3%95 https://chat.xutongbao.top/...
kubernetes基于helm部署gitlab
kubernetes基于helm部署gitlab 这篇博文介绍如何在 Kubernetes 中使用helm部署 GitLab。 先决条件 已运行的 Kubernetes 集群负载均衡器,为ingress-nginx控制器提供EXTERNAL-IP,本示例使用metallb默认存储类,为gitlab pods提供持久化存储&…...
jmeter 5.1彻底解决中文上传乱码
1.修改源码,然后重新打jar包,就是所有上传文件名重新获取文件名 参考链接:多种Jmeter中文乱码问题处理方法 - 51Testing软件测试网 2.修改Advanced,必须选java...
云运维工具
企业通常寻找具有成本效益的方法来优化创收,维护物理基础架构以托管服务器和应用程序以提供服务交付需要巨大的空间和前期资金,最重要的是,物理基础设施会产生额外的运营支出以进行定期维护,这对收入造成了沉重的损失。 云使企业…...
【RL】Wasserstein距离-GAN背后的直觉
一、说明 在本文中,我们将阅读有关Wasserstein GANs的信息。具体来说,我们将关注以下内容:i)什么是瓦瑟斯坦距离?,ii)为什么要使用它?iii) 我们如何使用它来训练 GAN&…...
sentinel引入CommonFilter类
最近在做一个springcloudAlibaba项目,做链路流控模式时需要将入口资源关闭聚合,做法如下: spring-cloud-alibaba v2.1.1.RELEASE及前,sentinel1.7.0及后: 1.pom 中引入: <dependency><groupId>…...
Phoenix创建local index失败
执行创建local index出现如下错误 0: jdbc:phoenix:hbase01:2181> create local index local_index_name on "test" ("user"."name","user"."address"); 23/07/28 17:28:56 WARN client.SyncCoprocessorRpcChannel: Cal…...
css3 hover border 流动效果
/* Hover 边线流动 */.hoverDrawLine {border: 0 !important;position: relative;border-radius: 5px;--border-color: #60daaa; } .hoverDrawLine::before, .hoverDrawLine::after {box-sizing: border-box;content: ;position: absolute;border: 2px solid transparent;borde…...
jdk安装
JDK的下载、安装和环境配置教程(2021年,win10)_「已注销」的博客-CSDN博客_jdk 以上文章如果没有成功在环境变量中part再添加一句 C:\Program Files (x86)\Java\jdk1.7.0_80\bin 安装目录下的bin目录 写完环境后重启 📎jdk-20_w…...
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造,完美适配AGV和无人叉车。同时,集成以太网与语音合成技术,为各类高级系统(如MES、调度系统、库位管理、立库等)提供高效便捷的语音交互体验。 L…...
铭豹扩展坞 USB转网口 突然无法识别解决方法
当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...
云计算——弹性云计算器(ECS)
弹性云服务器:ECS 概述 云计算重构了ICT系统,云计算平台厂商推出使得厂家能够主要关注应用管理而非平台管理的云平台,包含如下主要概念。 ECS(Elastic Cloud Server):即弹性云服务器,是云计算…...
树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频
使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...
【Oracle APEX开发小技巧12】
有如下需求: 有一个问题反馈页面,要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据,方便管理员及时处理反馈。 我的方法:直接将逻辑写在SQL中,这样可以直接在页面展示 完整代码: SELECTSF.FE…...
定时器任务——若依源码分析
分析util包下面的工具类schedule utils: ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类,封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz,先构建任务的 JobD…...
ios苹果系统,js 滑动屏幕、锚定无效
现象:window.addEventListener监听touch无效,划不动屏幕,但是代码逻辑都有执行到。 scrollIntoView也无效。 原因:这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作,从而会影响…...
华硕a豆14 Air香氛版,美学与科技的馨香融合
在快节奏的现代生活中,我们渴望一个能激发创想、愉悦感官的工作与生活伙伴,它不仅是冰冷的科技工具,更能触动我们内心深处的细腻情感。正是在这样的期许下,华硕a豆14 Air香氛版翩然而至,它以一种前所未有的方式&#x…...
回溯算法学习
一、电话号码的字母组合 import java.util.ArrayList; import java.util.List;import javax.management.loading.PrivateClassLoader;public class letterCombinations {private static final String[] KEYPAD {"", //0"", //1"abc", //2"…...
基于SpringBoot在线拍卖系统的设计和实现
摘 要 随着社会的发展,社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 在线拍卖系统,主要的模块包括管理员;首页、个人中心、用户管理、商品类型管理、拍卖商品管理、历史竞拍管理、竞拍订单…...
