序列化方法

序列化(Serialization)是将对象转换为可存储或传输的格式的过程。对于 Java 中的 JSON 序列化,通常是将 Java 对象转换成 JSON 字符串,以便传输到网络中或保存到文件中。反序列化则是将 JSON 字符串转换回 Java 对象的过程。

在 Jackson 中,序列化的核心任务是将 Java 对象转换为 JSON 格式。ObjectMapper 类在 Jackson 库中提供了非常方便的 API 来实现这一过程。

java 复制代码
import com.fasterxml.jackson.databind.ObjectMapper;

public class SerializationExample {
    public static void main(String[] args) throws Exception {
        // 创建一个 Person 对象
        Person person = new Person("John", 30);

        // 创建 ObjectMapper 实例
        ObjectMapper objectMapper = new ObjectMapper();

        // 序列化:Java 对象转 JSON 字符串
        String jsonString = objectMapper.writeValueAsString(person);
        System.out.println(jsonString);
    }
}

结果

{"name":"John","age":30}

序列化的详细过程

在 Jackson 中,序列化的过程包含以下步骤:

  • 获取 Java 对象的类信息:Jackson 会根据 Java 对象的类型,获取类的字段(属性)。
  • 转换 Java 对象的字段:它会遍历 Java 对象的属性,找到公共字段或通过 getter 方法访问属性,将其转化为相应的 JSON 键值对。
  • 生成 JSON 数据:这些键值对会被合并成一个 JSON 对象,转换过程最终生成 JSON 格式的字符串。

序列化底层实现概览

序列化的核心是 ObjectMapper 和它使用的一些辅助类,如 JsonGeneratorSerializerProviderJsonSerializer 等。具体的底层实现逻辑可以分为几个主要步骤:

  1. 找到正确的序列化器 (JsonSerializer)
  2. 通过 JsonGenerator 写出 JSON 数据
  3. 处理属性、类型等定制逻辑

序列化方法

ObjectMapper.writeValue()

ObjectMapper 是 Jackson 序列化和反序列化的核心工具,它提供了多种方法来实现序列化。例如,writeValueAsString() 将 Java 对象转换为 JSON 字符串,writeValue() 将 Java 对象写入到输出流中。

  1. 序列化流程解析

2.1. 处理 null

首先,在序列化过程中,ObjectMapper 会判断对象是否为 null。如果是 null,它会调用 _serializeNull() 方法,这通常会生成 JSON 中的 "null" 字符串。

2.2. 获取序列化器

如果对象不为 nullObjectMapper 会根据对象的类型(即 value.getClass())从 SerializerProvider 中查找合适的序列化器(JsonSerializer)。SerializerProvider 会缓存已经创建过的序列化器,并根据需要提供给 ObjectMapper

java 复制代码
public JsonSerializer<Object> findValueSerializer(Class<?> valueType, SerializationConfig config) {
    // 从缓存中查找序列化器,如果没有则创建新的序列化器
    JsonSerializer<Object> serializer = _serializerCache.get(valueType);
    if (serializer == null) {
        // 通过类型创建一个新的序列化器
        serializer = _createSerializer(config, valueType);
        _serializerCache.put(valueType, serializer);
    }
    return serializer;
}

2.3. 调用序列化器的 serialize() 方法

一旦获得了合适的序列化器,ObjectMapper 就会调用序列化器的 serialize() 方法来将 Java 对象转换为 JSON 数据。

java 复制代码
public void serialize(Object value, JsonGenerator gen, SerializerProvider provider) throws IOException {
    // 实际的序列化过程
    gen.writeStartObject();  // 开始一个 JSON 对象
    // 通过遍历 Java 对象的字段并序列化每个字段
    gen.writeEndObject();    // 结束一个 JSON 对象
}

在序列化过程中,Jackson 会遍历 Java 对象的字段或 getter 方法,并将其转化为 JSON 中的键值对。例如,Person 类中的 nameage 字段会被转换为 JSON 对象中的 "name": "John", "age": 30

Jackson 通过反射机制或者使用 JavaBean 属性访问器(getter/setter)来获取 Java 对象的属性。这部分代码会遍历对象的属性,并调用相应的 writeXXX 方法将每个属性序列化为 JSON。

完整序列化示例

java 复制代码
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;

import java.io.IOException;

public class JacksonSerializationExample {
    public static void main(String[] args) throws Exception {
        // 创建一个 Java 对象
        Person person = new Person("John", 30);

        // 创建 ObjectMapper 实例
        ObjectMapper objectMapper = new ObjectMapper();

        // 序列化:Java 对象转 JSON 字符串
        String jsonString = objectMapper.writeValueAsString(person);
        System.out.println(jsonString);
    }
}

class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }
}

class PersonSerializer extends JsonSerializer<Person> {
    @Override
    public void serialize(Person person, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        gen.writeStartObject();  // 开始序列化对象
        gen.writeStringField("name", person.getName());  // 写入 name 字段
        gen.writeNumberField("age", person.getAge());    // 写入 age 字段
        gen.writeEndObject();  // 结束序列化对象
    }
}

findValueSerializer() 方法

findValueSerializer()SerializerProvider 中的一个重要方法,它的作用是返回一个适用于指定类型的序列化器。具体来说,方法的定义如下:

java 复制代码
public JsonSerializer<Object> findValueSerializer(Class<?> valueType, SerializationConfig config) {
    // 通过类型查找或创建序列化器
    JsonSerializer<Object> serializer = _serializerCache.get(valueType);
    if (serializer == null) {
        // 如果缓存中没有找到该类型的序列化器,则创建一个新的序列化器
        serializer = _createSerializer(config, valueType);
        _serializerCache.put(valueType, serializer);  // 缓存序列化器
    }
    return serializer;
}

findValueSerializer 的主要工作流程:

  1. 缓存查找 :首先,findValueSerializer() 会查看 _serializerCache 中是否已经存在针对给定类型(valueType)的序列化器。如果找到了,它直接返回该序列化器。

  2. 序列化器创建 :如果缓存中没有该类型的序列化器,findValueSerializer() 会通过 _createSerializer() 方法创建一个新的序列化器。该方法根据对象类型、配置和其他因素(如 @JsonSerialize 注解等)来选择和创建适当的序列化器。

  3. 缓存 :新的序列化器创建后,会被缓存到 _serializerCache 中,以提高性能,避免重复创建相同类型的序列化器。

缓存机制

Jackson 会缓存已经创建过的序列化器,以避免每次序列化时都需要重复创建新的序列化器。通过 _serializerCache.get(valueType),Jackson 会先从缓存中检查是否已有该类型的序列化器。如果没有,才会调用 _createSerializer() 创建一个新的序列化器。这大大提高了性能,尤其是在大量序列化相同类型对象时。

相关推荐
Starshime12 分钟前
【Java】网络套接字
java·开发语言·网络
等什么君!13 分钟前
学习反射(反射的使用,反射的应用场景)
java·开发语言·学习
“抚琴”的人14 分钟前
C#—LINQ详解及汇总
开发语言·c#·linq
TT哇15 分钟前
练习题 逆波兰表达式求值
java·开发语言
数据小小爬虫24 分钟前
如何利用Python爬虫获得1688按关键字搜索商品
开发语言·爬虫·python
始终奔跑在路上26 分钟前
shell8
开发语言·网络安全
Little丶Seven30 分钟前
Unity Runtime控制编辑器的一些操作
java·unity·编辑器
m0_7493175238 分钟前
蓝桥杯练习生第四天
java·算法·职场和发展·矩阵·蓝桥杯
JWASX1 小时前
【BUG记录】Apifox 参数传入 + 号变成空格的 BUG
java·bug·urlencoder·urldecoder