序列化方法

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

序列化 是指将对象的状态转换为一种 可存储可传输 的格式的过程。这种格式通常是字节流(如 JSON、XML 或二进制格式),可以存储在文件、数据库中,或者通过网络进行传输。在接收端,可以通过 反序列化(Deserialization) 将字节流重新还原为对象。

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

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 对象写入到输出流中。

2. 序列化流程解析

2.1. 处理 null

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

2.2. 获取序列化器

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

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 数据。

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。

完整序列化示例

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 中的一个重要方法,它的作用是返回一个适用于指定类型的序列化器。具体来说,方法的定义如下:

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() 创建一个新的序列化器。这大大提高了性能,尤其是在大量序列化相同类型对象时。

1. 手动实现 JSON 序列化

以下代码实现了将对象手动序列化为 JSON 格式,并从 JSON 字符串反序列化为对象。

import java.util.HashMap;
import java.util.Map;

class Person {
    private String name;
    private int age;

    public Person() {} // 无参构造函数

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

    // 序列化为 JSON 字符串
    public String toJson() {
        return "{" +
                "\"name\":\"" + name + "\"," +
                "\"age\":" + age +
                "}";
    }

    // 从 JSON 字符串反序列化为对象
    public static Person fromJson(String json) {
        Map<String, String> map = parseJson(json);
        return new Person(map.get("name"), Integer.parseInt(map.get("age")));
    }

    // 简单解析 JSON(不支持复杂 JSON,仅用于示例)
    private static Map<String, String> parseJson(String json) {
        Map<String, String> map = new HashMap<>();
        json = json.replace("{", "").replace("}", "").replace("\"", "");
        String[] entries = json.split(",");
        for (String entry : entries) {
            String[] keyValue = entry.split(":");
            map.put(keyValue[0].trim(), keyValue[1].trim());
        }
        return map;
    }

    @Override
    public String toString() {
        return "Person{name='" + name + "', age=" + age + '}';
    }
}

public class CustomJsonSerialization {
    public static void main(String[] args) {
        // 创建对象
        Person person = new Person("Alice", 25);

        // 序列化为 JSON
        String json = person.toJson();
        System.out.println("Serialized JSON: " + json);

        // 从 JSON 反序列化为对象
        Person deserializedPerson = Person.fromJson(json);
        System.out.println("Deserialized Object: " + deserializedPerson);
    }
}

2. 手动实现 XML 序列化

实现对象到 XML 格式的序列化和反序列化。

class Person {
    private String name;
    private int age;

    public Person() {} // 无参构造函数

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

    // 序列化为 XML 字符串
    public String toXml() {
        return "<Person>" +
                "<name>" + name + "</name>" +
                "<age>" + age + "</age>" +
                "</Person>";
    }

    // 从 XML 字符串反序列化为对象
    public static Person fromXml(String xml) {
        String name = xml.substring(xml.indexOf("<name>") + 6, xml.indexOf("</name>"));
        int age = Integer.parseInt(xml.substring(xml.indexOf("<age>") + 5, xml.indexOf("</age>")));
        return new Person(name, age);
    }

    @Override
    public String toString() {
        return "Person{name='" + name + "', age=" + age + '}';
    }
}

public class CustomXmlSerialization {
    public static void main(String[] args) {
        // 创建对象
        Person person = new Person("Bob", 30);

        // 序列化为 XML
        String xml = person.toXml();
        System.out.println("Serialized XML: " + xml);

        // 从 XML 反序列化为对象
        Person deserializedPerson = Person.fromXml(xml);
        System.out.println("Deserialized Object: " + deserializedPerson);
    }
}

3. 手动实现二进制序列化

二进制序列化是将对象的数据写入字节流。以下是手动将对象序列化为字节数组并反序列化的实现:

class Person {
    private String name;
    private int age;

    public Person() {} // 无参构造函数

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

    // 序列化为 XML 字符串
    public String toXml() {
        return "<Person>" +
                "<name>" + name + "</name>" +
                "<age>" + age + "</age>" +
                "</Person>";
    }

    // 从 XML 字符串反序列化为对象
    public static Person fromXml(String xml) {
        String name = xml.substring(xml.indexOf("<name>") + 6, xml.indexOf("</name>"));
        int age = Integer.parseInt(xml.substring(xml.indexOf("<age>") + 5, xml.indexOf("</age>")));
        return new Person(name, age);
    }

    @Override
    public String toString() {
        return "Person{name='" + name + "', age=" + age + '}';
    }
}

public class CustomXmlSerialization {
    public static void main(String[] args) {
        // 创建对象
        Person person = new Person("Bob", 30);

        // 序列化为 XML
        String xml = person.toXml();
        System.out.println("Serialized XML: " + xml);

        // 从 XML 反序列化为对象
        Person deserializedPerson = Person.fromXml(xml);
        System.out.println("Deserialized Object: " + deserializedPerson);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值