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.mzph.cn/news/803244.shtml

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

相关文章

因为使用ArrayList.removeAll(List list)导致的机器重启

背景 先说一下背景&#xff0c;博主所在的业务组有一个核心系统&#xff0c;需要同步两个不同数据源给过来的数据到redis中&#xff0c;但是每次同步之前需要过滤掉一部分数据&#xff0c;只存储剩下的数据。每次同步的数据与需要过滤掉的数据量级大概在0-100w的数据不等。 由…

tmux 替换 nohup

替换方案 tmux 训练PyTorch模型的时候一个基本步骤&#xff1a; [terminal]: tmux new -s model-ft # 创建一个会话&#xff0c;并设置会话名:model-ft [tmux]: conda activate your_env # 在tmux会话中&#xff0c;我们激活我们要使用的conda环境 [tmux]: pyth…

JVM_垃圾收集器

GC垃圾收集器 文章目录 GC垃圾收集器GC垃圾回收算法和垃圾收集器关系GC算法主要有以下几种四种主要的垃圾收集器SerialParallelCMSG1垃圾收集器总结查看默认垃圾收集器 默认垃圾收集器有哪些各垃圾收集器的使用范围部分参数说明 新生代下的垃圾收集器并行GC(ParNew)并行回收GC&…

【C++航海王:追寻罗杰的编程之路】探寻实用的调试技巧

目录 1 -> 什么是bug&#xff1f; 2 -> 调试是什么&#xff1f;有多重要&#xff1f; 2.1 -> 调试是什么&#xff1f; 2.2 -> 调试的基本步骤 2.3 -> Debug和Release的介绍 3 -> Windows环境调试介绍 3.1 -> 调试环境的准备 3.2 -> 学会快捷键…

:-1: error: Project ERROR: msvc-version.conf loaded but QMAKE_MSC_VER isn‘t set

qt报错 错误1 : error: Project ERROR: msvc-version.conf loaded but QMAKE_MSC_VER isnt set 错误1 : error: Project ERROR: msvc-version.conf loaded but QMAKE_MSC_VER isn’t set bug的现象:qtcreator无法通过点击pro文件来打开项目 方法:参考 根据上面的参考,我么找到…

【React】React hooks 清除定时器并验证效果

React hooks 清除定时器并验证效果 目录结构如下useTime hookClock.tsx使用useTime hookApp.tsx显示Clock组件显示时间&#xff08;开启定时器&#xff09;隐藏时间&#xff08;清除定时器&#xff09; 总结参考 目录结构如下 useTime hook // src/hooks/common.ts import { u…

三角测量法恢复深度

参考&#xff1a;单目vo中的深度确定方法--三角测量_单目相机三角测量-CSDN博客 方法一&#xff1a;直接法 由于我们已经通过本质矩阵分解或者单应矩阵分解获得了R与t&#xff0c;此时想求的是两个特征点的深度 bool depthFromTriangulation(const SE3& T_search_ref,co…

电脑开机提示“no bootable device”,无法进入系统

当您的Windows 10电脑开机时提示“no bootable device”,这意味着计算机无法找到一个可以启动操作系统的设备。这个问题通常与硬件连接、BIOS设置、硬盘问题、引导扇区故障或系统文件损坏等有关。以下是一系列详细的解决步骤: 检查硬件连接:关闭电脑,拔掉电源线,打开机箱检…

Flutter之TabBar篇

总结了一下项目中用到的几种TabBar&#xff0c;针对不同的样式&#xff0c;有采用系统提供的&#xff0c;也有三方插件提供的&#xff0c;也有自定义的&#xff0c;效果如下&#xff08;后续如果遇到新的样式&#xff0c;会不间断地记录更新&#xff0c;避免重复造轮子…&#…

性能分析-数据库与磁盘知识

数据库 数据库&#xff0c;其实是数据库管理系统dbms。 数据库管理系统&#xff0c; 常见&#xff1a; 关系型数据库&#xff1a; mysql、pg、 库的表&#xff0c;表与表之间有关联关系&#xff1b; 表二维表统一标准的SQL&#xff08;不局限于CRUD&#xff09;非关系型数据…

ssm034学生请假系统+jsp

学生请假系统设计与实现 摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本学生请假系统就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处…

鸿蒙HarmonyOS开发实例:【简单时钟】

简单时钟 介绍 本示例通过使用[ohos.display]接口以及Canvas组件来实现一个简单的时钟应用。 效果预览 主页 使用说明 1.界面通过setInterval实现周期性实时刷新时间&#xff0c;使用Canvas绘制时钟&#xff0c;指针旋转角度通过计算得出。 例如&#xff1a;"2 * M…

Microsoft Visio 参与者 [actor] - 人的形状图标

Microsoft Visio 参与者 [actor] - 人的形状图标 1. 更多形状 -> 搜索形状2. 参与者References 1. 更多形状 -> 搜索形状 2. 参与者 References [1] Yongqiang Cheng, https://yongqiang.blog.csdn.net/

【简单讲解下如何Java中文乱码浅析及解决方案】

&#x1f308;个人主页: 程序员不想敲代码啊 &#x1f3c6;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f44d;点赞⭐评论⭐收藏 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共…

力扣经典150题(1)

文章目录 6.Z字形变换82.删除排序链表中的重复元素||61.旋转链表100.相同的树 6.Z字形变换 将一个给定字符串 s 根据给定的行数 numRows &#xff0c;以从上往下、从左到右进行 Z 字形排列。 比如输入字符串为 “PAYPALISHIRING” 行数为 3 时&#xff0c;排列如下&#xff1…

Spring循环依赖

Java开发常见面试题详解&#xff08;LockSupport&#xff0c;AQS&#xff0c;Spring循环依赖&#xff0c;Redis&#xff09;_java 常见面试题详解(locksupport-CSDN博客 循环依赖现象在spring容器中注入依赖的对象&#xff0c;有2种情况 构造器方式注入依赖&#xff08;不可行…

基于遗传优化的SVD水印嵌入提取算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 5.完整程序 1.程序功能描述 基于遗传优化的的SVD水印嵌入提取算法。对比遗传优化前后SVD水印提取性能&#xff0c;并分析不同干扰情况下水印提取效果。 2.测试软件版本以及运行结果展示 MA…

根据mysql的执行顺序来写select

过滤顺序指的是mysql的逻辑执行顺序&#xff0c;个人觉得我们可以按照执行顺序来写select查询语句。 目录 一、执行顺序二、小tips三、案例第一轮查询&#xff1a;统计每个num的出现次数第二轮查询&#xff1a;计算**最多次数**第三轮查询&#xff1a;找到所有出现次数为最多次…

Linux使用宝塔面板安装MySQL结合内网穿透实现公网连接本地数据库

文章目录 推荐前言1.Mysql服务安装2.创建数据库3.安装cpolar3.2 创建HTTP隧道 4.远程连接5.固定TCP地址5.1 保留一个固定的公网TCP端口地址5.2 配置固定公网TCP端口地址 推荐 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不…

【docker】Docker 简介

Docker 简介 什么是虚拟化、容器化?为什么要虚拟化、容器化&#xff1f;虚拟化实现方式应用程序执行环境分层虚拟化常见类别虚拟机容器JVM 之类的虚拟机 常见虚拟化实现主机虚拟化(虚拟机)实现容器虚拟化实现容器虚拟化实现原理容器虚拟化基础之 NameSpace 什么是虚拟化、容器…