序列化(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
和它使用的一些辅助类,如 JsonGenerator
、SerializerProvider
、JsonSerializer
等。具体的底层实现逻辑可以分为几个主要步骤:
- 找到正确的序列化器 (
JsonSerializer
) - 通过
JsonGenerator
写出 JSON 数据 - 处理属性、类型等定制逻辑
序列化方法
ObjectMapper.writeValue()
ObjectMapper
是 Jackson 序列化和反序列化的核心工具,它提供了多种方法来实现序列化。例如,writeValueAsString()
将 Java 对象转换为 JSON 字符串,writeValue()
将 Java 对象写入到输出流中。
- 序列化流程解析
2.1. 处理 null
值
首先,在序列化过程中,ObjectMapper
会判断对象是否为 null
。如果是 null
,它会调用 _serializeNull()
方法,这通常会生成 JSON 中的 "null"
字符串。
2.2. 获取序列化器
如果对象不为 null
,ObjectMapper
会根据对象的类型(即 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
类中的 name
和 age
字段会被转换为 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
的主要工作流程:
-
缓存查找 :首先,
findValueSerializer()
会查看_serializerCache
中是否已经存在针对给定类型(valueType
)的序列化器。如果找到了,它直接返回该序列化器。 -
序列化器创建 :如果缓存中没有该类型的序列化器,
findValueSerializer()
会通过_createSerializer()
方法创建一个新的序列化器。该方法根据对象类型、配置和其他因素(如@JsonSerialize
注解等)来选择和创建适当的序列化器。 -
缓存 :新的序列化器创建后,会被缓存到
_serializerCache
中,以提高性能,避免重复创建相同类型的序列化器。
缓存机制
Jackson 会缓存已经创建过的序列化器,以避免每次序列化时都需要重复创建新的序列化器。通过 _serializerCache.get(valueType)
,Jackson 会先从缓存中检查是否已有该类型的序列化器。如果没有,才会调用 _createSerializer()
创建一个新的序列化器。这大大提高了性能,尤其是在大量序列化相同类型对象时。