Jackson 2.x 系列【15】序列化器 JsonSerializer

有道无术,术尚可求,有术无道,止于术。

本系列Jackson 版本 2.17.0

源码地址:https://gitee.com/pearl-organization/study-jaskson-demo

文章目录

    • 1. 概述
    • 2. 方法
      • 2.1 构造
      • 2.2 序列化
      • 2.3 其他
    • 3. 实现类
      • 3.1 StdSerializer
        • 3.1.1 源码
        • 3.1.2 ContainerSerializer
        • 3.1.3 ToStringSerializerBase
        • 3.1.4 NullSerializer
        • 3.1.5 BeanSerializerBase
      • 3.2 None
      • 3.3 TypeWrappedSerializer

1. 概述

JsonSerializer是一个用于序列化Java对象为JSON的抽象类,是Jackson中的重要组件之一。

2. 方法

JsonSerializer没有成员属性,但是声明了很多方法。

2.1 构造

Fluent风格的工厂方法用于构建经过装饰或增强的序列化器对象。

    /*** 未包装的序列化器对象** @param unwrapper 用于在包装器属性名称之间转换的名称转换器*/public JsonSerializer<T> unwrappingSerializer(NameTransformer unwrapper) {return this;}/*** 用于尝试替换此序列化器所委托调用的序列化器,如果不支持,则应抛出 {@link UnsupportedOperationException}或者直接返回此序列化器本身。** @since 2.1*/public JsonSerializer<T> replaceDelegatee(JsonSerializer<?> delegatee) {throw new UnsupportedOperationException();}/*** 支持过滤的子类,如果过滤器发生变化,则需要创建并返回新的实例。** @since 2.6*/public JsonSerializer<?> withFilterId(Object filterId) {return this;}/*** 用于在排除指定名称的属性集后创建新的实例(如果存在的话)** @param ignoredProperties  忽略序列化的一组属性名称* @return 序列化器实例,它不会忽略指定的属性集(如果存在的话)* @since 2.16*/public JsonSerializer<?> withIgnoredProperties(Set<String> ignoredProperties) {return this;}

2.2 序列化

序列化是将对象状态转换为可以存储或传输的形式的过程,JsonGenerator声明了两个序列化方法,这是我们需要关注的重点。

    /*** 序列化** @param value       要序列化的值,不能为null* @param gen         用于输出Json内容的生成器* @param serializers 提供者,可用于获取序列化包含在值中的对象所需的序列化器(如果有的话)*/public abstract void serialize(T value, JsonGenerator gen, SerializerProvider serializers) throws IOException;/*** 使用指定的类型序列化器来序列化** @param value       要序列化的值,不能为null* @param gen         用于输出Json内容的生成器* @param serializers 提供者,可用于获取序列化包含在值中的对象所需的序列化器(如果有的话)* @param typeSer     指定的类型序列化器*/public void serializeWithType(T value, JsonGenerator gen, SerializerProvider serializers, TypeSerializer typeSer) throws IOException {Class<?> clz = handledType();if (clz == null) {clz = value.getClass();}serializers.reportBadDefinition(clz, String.format("Type id handling not implemented for type %s (by serializer of type %s)", clz.getName(), getClass().getName()));}

2.3 其他

其他的一些方法,了解即可。

    /*** 获取序列化器可以处理的对象类型*/public Class<T> handledType() {return null;}/*** 检查可序列化值是否被视为“空”值(用于抑制空值的序列化)。** @deprecated 自2.5版本起,请使用 {@link #isEmpty(SerializerProvider, Object)} 替代,在3.0版本中将被移除。*/@Deprecatedpublic boolean isEmpty(T value) {return isEmpty(null, value);}/*** 检查可序列化值是否被视为“空”值(用于抑制空值的序列化)。** @since 2.5*/public boolean isEmpty(SerializerProvider provider, T value) {return (value == null);}/*** 查询此序列化器实例是否将使用ObjectId来处理循环引用。*/public boolean usesObjectId() {return false;}/*** 用于检查此序列化器是否为“解包”序列化器*/public boolean isUnwrappingSerializer() {return false;}/*** 用于确定此序列化器是否通过使用另一个序列化器进行实际序列化(通过委托调用),如果是,则返回该序列化器,否则返回null。** @since 2.1*/public JsonSerializer<?> getDelegatee() {return null;}/*** 迭代此序列化器所处理类型的逻辑属性。** @since 2.6*/public Iterator<PropertyWriter> properties() {return ClassUtil.emptyIterator();}/*** 默认实现只是调用 {@link JsonFormatVisitorWrapper#expectAnyFormat(JavaType)}。** @since 2.1*/@Overridepublic void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType type) throws JsonMappingException {visitor.expectAnyFormat(type);}

3. 实现类

JsonSerializer有很多的实现类,用于处理各种数据类型。

在这里插入图片描述

3.1 StdSerializer

StdSerializer即标准的序列化器,也是一个抽象类,是在JsonSerializer的基础上封装了一些通用方法,实现序列化器时,应该继承该类,而不是JsonSerializer

3.1.1 源码

StdSerializer声明了两个成员属性和一些构造方法:

    /*** 用于存储锁对象的键,以防止在构造转换序列化器时发生无限递归** @since 2.9*/private final static Object KEY_CONTENT_CONVERTER_LOCK = new Object();/*** 支持的类型,通常是所使用的序列化器对应属性的声明类型。*/protected final Class<T> _handledType;protected StdSerializer(Class<T> t) {_handledType = t;}@SuppressWarnings("unchecked")protected StdSerializer(JavaType type) {_handledType = (Class<T>) type.getRawClass();}/***  用来解决泛型类型处理中的一些问题*/@SuppressWarnings("unchecked")protected StdSerializer(Class<?> t, boolean dummy) {_handledType = (Class<T>) t;}/*** @since 2.6*/@SuppressWarnings("unchecked")protected StdSerializer(StdSerializer<?> src) {_handledType = (Class<T>) src._handledType;}

核心的序列化方法任然是抽象的,需要子类去实现:

    @Overridepublic abstract void serialize(T value, JsonGenerator gen, SerializerProvider provider)throws IOException;

提供了很多辅助方法,供子类调用,例如用于标识底层JSON类型的方法:

    /*** 辅助方法,用于调用必要的访问方法,以指示底层JSON类型为JSON字符串。** @since 2.7*/protected void visitStringFormat(JsonFormatVisitorWrapper visitor, JavaType typeHint)throws JsonMappingException {/*JsonStringFormatVisitor v2 =*/visitor.expectStringFormat(typeHint);}/*** 辅助方法,用于调用必要的访问方法,以指示底层JSON类型为JSON字符串,但存在更精细的逻辑类型。** @since 2.7*/protected void visitStringFormat(JsonFormatVisitorWrapper visitor, JavaType typeHint,JsonValueFormat format)throws JsonMappingException {JsonStringFormatVisitor v2 = visitor.expectStringFormat(typeHint);if (v2 != null) {v2.format(format);}}/*** 辅助方法,用于调用必要的访问方法,以指示底层JSON类型为JSON整数。** @since 2.7*/protected void visitIntFormat(JsonFormatVisitorWrapper visitor, JavaType typeHint,NumberType numberType)throws JsonMappingException {JsonIntegerFormatVisitor v2 = visitor.expectIntegerFormat(typeHint);if (_neitherNull(v2, numberType)) {v2.numberType(numberType);}}/*** 辅助方法,用于调用必要的访问方法,以指示底层JSON类型为JSON整数,但还涉及进一步的格式限制。** @since 2.7*/protected void visitIntFormat(JsonFormatVisitorWrapper visitor, JavaType typeHint,NumberType numberType, JsonValueFormat format)throws JsonMappingException {JsonIntegerFormatVisitor v2 = visitor.expectIntegerFormat(typeHint);if (v2 != null) {if (numberType != null) {v2.numberType(numberType);}if (format != null) {v2.format(format);}}}/*** 辅助方法,用于调用必要的访问方法,以指示底层JSON类型为浮点型JSON数字。** @since 2.7*/protected void visitFloatFormat(JsonFormatVisitorWrapper visitor, JavaType typeHint,NumberType numberType)throws JsonMappingException {JsonNumberFormatVisitor v2 = visitor.expectNumberFormat(typeHint);if (v2 != null) {v2.numberType(numberType);}}/*** @since 2.7*/protected void visitArrayFormat(JsonFormatVisitorWrapper visitor, JavaType typeHint,JsonSerializer<?> itemSerializer, JavaType itemType)throws JsonMappingException {JsonArrayFormatVisitor v2 = visitor.expectArrayFormat(typeHint);if (_neitherNull(v2, itemSerializer)) {v2.itemsFormat(itemSerializer, itemType);}}/*** @since 2.7*/protected void visitArrayFormat(JsonFormatVisitorWrapper visitor, JavaType typeHint,JsonFormatTypes itemType)throws JsonMappingException {JsonArrayFormatVisitor v2 = visitor.expectArrayFormat(typeHint);if (v2 != null) {v2.itemsFormat(itemType);}}

用于包装处理异常的辅助方法:

   public void wrapAndThrow(SerializerProvider provider,Throwable t, Object bean, String fieldName)throws IOException { //..............}public void wrapAndThrow(SerializerProvider provider,Throwable t, Object bean, int index)throws IOException {//..............}

和注解相关的辅助方法:

    /*** 用于检查指定的属性是否具有指示需要对包含的值(结构化类型的内容;数组/列表/映射值)使用转换器的注解。*/protected JsonSerializer<?> findContextualConvertingSerializer(SerializerProvider provider,BeanProperty property, JsonSerializer<?> existingSerializer)throws JsonMappingException { //..............}/*** 根据 ID 查询 PropertyFilter*/protected PropertyFilter findPropertyFilter(SerializerProvider provider,Object filterId, Object valueToFilter)throws JsonMappingException {//..............}/*** 辅助方法,可用于查找此反序列化器是否具有特定的 {@link JsonFormat} 设置*/protected JsonFormat.Value findFormatOverrides(SerializerProvider provider,BeanProperty prop, Class<?> typeForDefaults) {//..............}/*** 查找JsonFormat.Feature特性是否已被特别标记为启用或禁用*/protected Boolean findFormatFeature(SerializerProvider provider,BeanProperty prop, Class<?> typeForDefaults, JsonFormat.Feature feat) {//..............}/*** 查找是否包含@JsonInclude.Value*/protected JsonInclude.Value findIncludeOverrides(SerializerProvider provider,BeanProperty prop, Class<?> typeForDefaults) {//..............}/*** 辅助方法,用于查找可能已配置的内容值序列化器。*/protected JsonSerializer<?> findAnnotatedContentSerializer(SerializerProvider serializers,BeanProperty property)throws JsonMappingException {//..............}
3.1.2 ContainerSerializer

Jackson默认提供了很多StdSerializer的实现类:

在这里插入图片描述
这里挑出一些常用的进行讲解,首先是ContainerSerializer,可以直接看出是用于集合类型的序列化:

在这里插入图片描述

示例,在序列化List<T>时,调用的是IndexedListSerializer

        JsonMapper jsonMapper = JsonMapper.builder().build();List<String> list=new ArrayList<>();list.add("haha");list.add("heihei");String jsonValue = jsonMapper.writeValueAsString(list);System.out.println(jsonValue);
3.1.3 ToStringSerializerBase

ToStringSerializerBase用于将值序列化为字符串,支持BigDecimalZoneIdString类型:
在这里插入图片描述

3.1.4 NullSerializer

NullSerializer用于序列化null值,可以看到直接调用了JsonGenerator.writeNull()方法,JSON中直接使用null表示:

    public void serialize(Object value, JsonGenerator gen, SerializerProvider provider) throws IOException {gen.writeNull();}public void serializeWithType(Object value, JsonGenerator gen, SerializerProvider serializers, TypeSerializer typeSer) throws IOException {gen.writeNull();}
3.1.5 BeanSerializerBase

BeanSerializerBase是一个用于序列化JavaBean对象的基础类,提供了一些可重用且可扩展的方法,开发者可以只注重于实现自定义的序列化逻辑。

BeanSerializerBase会处理 JavaBean 的一些通用特性,如属性的访问(通过 gettersetter 方法)、属性的过滤(基于注解或其他配置)、属性的排序等。

其包含了几个实现类,其中BeanSerializer是标准实现:

在这里插入图片描述

3.2 None

NoneJsonSerializer的一个内部抽象类,用于标识@JsonSerialize注解,明确表示不使用任何特定的序列化器,而是使用默认的序列化机制。

/*** 注解 {@link com.fasterxml.jackson.databind.annotation.JsonSerialize} 的标记*/
public abstract static class None extends JsonSerializer<Object> {
}

@JsonSerialize中可以看到默认用的None,表示没有指定序列化器(使用默认的):

@JacksonAnnotation
public @interface JsonSerialize {Class<? extends JsonSerializer> using() default JsonSerializer.None.class;//.......

3.3 TypeWrappedSerializer

TypeWrappedSerializer类型包装序列化器,可以看到有一个TypeSerializer 和一个JsonSerializer属性,序列化都是调用JsonSerializerserializeWithType方法。

很好理解,这是一个包装模式,包装JsonSerializer使用指定的TypeSerializer 进行序列化。

	protected final TypeSerializer _typeSerializer;protected final JsonSerializer<Object> _serializer;public void serialize(Object value, JsonGenerator g, SerializerProvider provider) throws IOException {this._serializer.serializeWithType(value, g, provider, this._typeSerializer);}public void serializeWithType(Object value, JsonGenerator g, SerializerProvider provider, TypeSerializer typeSer) throws IOException {this._serializer.serializeWithType(value, g, provider, typeSer);}

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

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

相关文章

vue3学习笔记(pinia)

defineModel&#xff1a;快速实现组件的双向绑定 pinia&#xff1a;在仓库中提供数据和使用数据 创建store文件夹&#xff0c;在里面创建counter.js&#xff0c;以提供数据&#xff0c;注意需要return 和 export&#xff0c;export的是一个函数。 import { defineStore } from…

智慧驿站式的“智慧公厕”,给城市新基建带来新变化

随着智慧城市建设的推进&#xff0c;智慧驿站作为一种多功能城市部件&#xff0c;正逐渐在城市中崭露头角。这些智慧驿站集合了智慧公厕的管理功能&#xff0c;为城市的新基建带来了全新的变革。本文以智慧驿站智慧公厕源头实力厂家广州中期科技有限公司&#xff0c;大量精品案…

蓝桥杯第十三届省赛C++B组(未完)

目录 刷题统计 修剪灌木 X进制减法 【前缀和双指针】统计子矩阵 【DP】积木画 【图DFS】扫雷 李白打酒加强版 DFS (通过64%&#xff0c;ACwing 3/11&#xff09;; DFS(AC) DP&#xff08;AC&#xff09; 砍竹子(X) 刷题统计 题目描述 小明决定从下周一开始努力刷题准…

基于JAVA的汽车售票网站论文

摘 要 互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播&#xff0c;搭配信息管理工具可以很好地为人们提供服务。针对汽车售票信息管理混乱&#xff0c;出错率高&#xff0c;信息安全性差…

ChatGPT与生成式AI:教育领域内新的浪潮与挑战

随着ChatGPT和其他生成式AI技术&#xff0c;如GPT-3.5、GPT-4的出现&#xff0c;我们正见证教育领域一场前所未有的变革浪潮。这些技术不仅推动了教育方式的进步&#xff0c;也为学习者带来了全新的机遇和挑战。 NO.1教育变革的新浪潮 生成式AI技术&#xff0c;特别是ChatGPT&…

使用SquareLine Studio创建LVGL项目到IMX6uLL平台

文章目录 前言一、SquareLine Studio是什么&#xff1f;二、下载安装三、工程配置四、交叉编译 前言 遇到的问题&#xff1a;#error LV_COLOR_DEPTH should be 16bit to match SquareLine Studios settings&#xff0c;解决方法见# 四、交叉编译 一、SquareLine Studio是什么…

04 Python进阶:MySQL-PyMySQL

什么是 PyMySQL&#xff1f; PyMySQL 是一个用于 Python 的纯 Python MySQL 客户端库&#xff0c;提供了与 MySQL 数据库进行交互的功能。PyMySQL 允许 Python 开发人员连接到 MySQL 数据库服务器&#xff0c;并执行诸如查询、插入、更新和删除等数据库操作。 以下是 PyMySQL …

超图SuperMap-Cesium,地形图层,可以渲染一个或多个地形(地形可缓存DEM,TIN方式),webGL代码开发(2024-04-08)

1、缓存文件类型TIN格式&#xff0c;TIN的地形sct只能加一个 const viewer new Cesium.Viewer(cesiumContainer); viewer.terrainProvider new Cesium.CesiumTerrainProvider({isSct: true, // 是否为iServer发布的TIN地形服务,stk地形设置为falserequestWaterMask : true,…

【前沿模型解析】潜在扩散模型 2-2 | 手撕感知图像压缩基础块上下sample块

文章目录 1 DownSample下采样部分1.1 两种实现方式1.2 代码实现 2 UpSample上采样部分2.1 代码实现 1 DownSample下采样部分 1.1 两种实现方式 下采样&#xff0c;即改变特征图的尺寸 下采样的话源码实现了两种方式 方式一&#xff1a;是通过卷积实现下采样&#xff0c;我们…

谈谈什么是 Redis

&#x1f525;博客主页&#xff1a;fly in the sky - CSDN博客 &#x1f680;欢迎各位&#xff1a;点赞&#x1f44d;收藏⭐️留言✍️&#x1f680; &#x1f386;慢品人间烟火色,闲观万事岁月长&#x1f386; &#x1f4d6;希望我写的博客对你有所帮助,如有不足,请指正&#…

Linux(05) Debian 系统修改主机名

查看主机名 方法1&#xff1a;hostname hostname 方法2&#xff1a;cat etc/hostname cat /etc/hostname 如果在创建Linux系统的时候忘记修改主机名&#xff0c;可以采用以下的方式来修改主机名称。 修改主机名 注意&#xff0c;在linux中下划线“_”可能是无效的字符&…

软件测试学习之MySQL学习笔记(完结)

目录 1. 数据库**** 1.1. 概念**** 1.2. 分类**** 1.2.1. 关系型数据库**** 1.2.1.1. SQL**** 1.2.2. 安装**** 1.2.2.1. Navicat**** 2. SQL语句**** 2.1. 常用数据类型**** 2.2. 数据库**** 2.3. 表**** 2.3.1. 字段约束**** 2.4. 数据**** 2.4.1. 增 insert**…

JavaSE:图书管理系统

目录 一、前言 二、内容需求 三、类的设计 &#xff08;一&#xff09;图书类 1.Book 类 2.BookList 类 &#xff08;二&#xff09;操作类 1.添加图书AddOperation类 2.借阅图书BorrowOperation类 3.删除图书DelOperation类 4.显示图书ShowOperation类 5.退出系统Ex…

ChromeOS 中自启动 Fcitx5 和托盘 stalonetray

ChromeOS 更新的飞快&#xff0c;旧文章的方法也老是不好用&#xff0c;找遍了也没找到很好的可以开机自启动 Linux VM 和输入法、托盘的方法。 研究了一下&#xff08;不&#xff0c;是很久&#xff09;&#xff0c;终于找到个丑陋的实现。 方法基于 ChromeOS 123.0.6312.94…

linux 开机自启动

方式1—依赖桌面启动&#xff0c;一般适用与UI相关程序 1、创建运行脚本&#xff0c;以管理员放方式运行&#xff0c;加入密码 vim runapp.sh #!/bin/bash cd /home/nvidia/test echo ‘passcode’ | sudo -S ./testapp 2、终端输入 gnome-session-properties 3、在com…

os.listdir()bug总结

今天测试出一个神奇的bug&#xff0c;算是教训吧&#xff0c;找了两天不知道问题在哪&#xff0c;最后才发现问题出现在这 原始文件夹显示 os.listdir()结果乱序 import os base_path "./file/"files os.listdir(base_path)print(files)问题原因 解决办法(排序) …

即插即用篇 | YOLOv8引入Haar小波下采样 | 一种简单而有效的语义分割下采样模块

本改进已集成到 YOLOv8-Magic 框架。 下采样操作如最大池化或步幅卷积在卷积神经网络(CNNs)中被广泛应用,用于聚合局部特征、扩大感受野并减少计算负担。然而,对于语义分割任务,对局部邻域的特征进行池化可能导致重要的空间信息丢失,这有助于逐像素预测。为了解决这个问题…

【进阶六】Python实现SDVRPTW常见求解算法——遗传算法(GA)

基于python语言&#xff0c;采用经典蚁群算法&#xff08;ACO&#xff09;对 带硬时间窗的需求拆分车辆路径规划问题&#xff08;SDVRPTW&#xff09; 进行求解。 目录 往期优质资源1. 适用场景2. 代码调整2.1 需求拆分2.2 需求拆分后的服务时长取值问题 3. 求解结果4. 代码片段…

智慧水库解决方案(打造水库智慧监测体系)

​作为一名水利自动化系统集成商,最近我司接手了一个智慧水库建设项目。这个项目位于一座山区的大型水库,目的是对其进行现代化、智能化改造,提升供水、防洪等管理水平。&#xff08;key-iot.com.cn&#xff09; 在方案设计之初,我们组织了现场勘测,全面了解水库的实际情况。这…

创建型模式--2.简单工厂模式【人造恶魔果实工厂1】

1. 工厂模式的特点 在海贼王中&#xff0c;作为原王下七武海之一的多弗朗明哥&#xff0c;可以说是新世界最大的流氓头子&#xff0c;拥有无上的权利和无尽的财富。他既是德雷斯罗萨国王又是地下世界的中介&#xff0c;控制着世界各地的诸多产业&#xff0c;人造恶魔果实工厂就…