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

您所在的位置:网站首页 jsonserialize注解处理嵌套序列化 Jackson 2.x 系列【15】序列化器 JsonSerializer

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

2024-07-11 09:55| 来源: 网络整理| 查看: 265

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

本系列Jackson 版本 2.17.0

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

文章目录 1. 概述2. 方法2.1 构造2.2 序列化2.3 其他 3. 实现类3.1 StdSerializer3.1.1 源码3.1.2 ContainerSerializer3.1.3 ToStringSerializerBase3.1.4 NullSerializer3.1.5 BeanSerializerBase 3.2 None3.3 TypeWrappedSerializer

1. 概述

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

2. 方法

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

2.1 构造

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

/** * 未包装的序列化器对象 * * @param unwrapper 用于在包装器属性名称之间转换的名称转换器 */ public JsonSerializer unwrappingSerializer(NameTransformer unwrapper) { return this; } /** * 用于尝试替换此序列化器所委托调用的序列化器,如果不支持,则应抛出 {@link UnsupportedOperationException}或者直接返回此序列化器本身。 * * @since 2.1 */ public JsonSerializer 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 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 handledType() { return null; } /** * 检查可序列化值是否被视为“空”值(用于抑制空值的序列化)。 * * @deprecated 自2.5版本起,请使用 {@link #isEmpty(SerializerProvider, Object)} 替代,在3.0版本中将被移除。 */ @Deprecated public 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 properties() { return ClassUtil.emptyIterator(); } /** * 默认实现只是调用 {@link JsonFormatVisitorWrapper#expectAnyFormat(JavaType)}。 * * @since 2.1 */ @Override public 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 _handledType; protected StdSerializer(Class t) { _handledType = t; } @SuppressWarnings("unchecked") protected StdSerializer(JavaType type) { _handledType = (Class) type.getRawClass(); } /** * 用来解决泛型类型处理中的一些问题 */ @SuppressWarnings("unchecked") protected StdSerializer(Class t, boolean dummy) { _handledType = (Class) t; } /** * @since 2.6 */ @SuppressWarnings("unchecked") protected StdSerializer(StdSerializer src) { _handledType = (Class) src._handledType; }

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

@Override public 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时,调用的是IndexedListSerializer:

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

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

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 的一些通用特性,如属性的访问(通过 getter 和 setter 方法)、属性的过滤(基于注解或其他配置)、属性的排序等。

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

在这里插入图片描述

3.2 None

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

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

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

@JacksonAnnotation public @interface JsonSerialize { Class using() default JsonSerializer.None.class; //....... 3.3 TypeWrappedSerializer

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

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

protected final TypeSerializer _typeSerializer; protected final JsonSerializer _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); }


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3