Кастомизация сериализации
Как изменить стандартное поведение сериализации/десериализации?
Чтобы изменить стандартное поведение сериализации/десериализации в Java, вы можете использовать методы writeObject и readObject внутри вашего класса, который реализует интерфейс Serializable.
import java.io.*;
public class Person implements Serializable {
private static final long serialVersionUID = 1L;
private String name;
private int age;
private transient String note; // не будет сериализовано стандартным способом
public Person(String name, int age, String note) {
this.name = name;
this.age = age;
this.note = note;
}
private void writeObject(ObjectOutputStream oos) throws IOException {
oos.defaultWriteObject(); // стандартная сериализация
oos.writeObject(encodeDemo(note)); // дополнительная логика (учебное преобразование строки)
}
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
ois.defaultReadObject(); // стандартная десериализация
note = decodeDemo((String) ois.readObject()); // дополнительная логика (обратное учебное преобразование строки)
}
private String encodeDemo(String data) {
return new StringBuilder(data).reverse().toString(); // обратимое преобразование, не шифрование
}
private String decodeDemo(String data) {
return new StringBuilder(data).reverse().toString(); // обратное преобразование
}
}
Как создать собственный протокол сериализации?
Для создания собственного протокола сериализации в Java можно использовать интерфейс Externalizable, который является расширением интерфейса Serializable. При использовании Externalizable вы должны реализовать методы writeExternal и readExternal, которые обеспечивают полный контроль над процессами сериализации и десериализации.
Пример использования Externalizable
-
Создание класса, реализующего интерфейс
Externalizable:
import java.io.*;
public class CustomSerializableClass implements Externalizable {
private String name;
private int age;
private transient String note; // Поле, которое не будет сериализовано стандартным способом
// Обязательный публичный конструктор без параметров
public CustomSerializableClass() {}
public CustomSerializableClass(String name, int age, String note) {
this.name = name;
this.age = age;
this.note = note;
}
@Override
public void writeExternal(ObjectOutput out) throws IOException {
out.writeUTF(name); // Кастомная логика сериализации
out.writeInt(age);
out.writeUTF(encodeDemo(note)); // Учебное преобразование строки перед сериализацией
}
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
name = in.readUTF(); // Кастомная логика десериализации
age = in.readInt();
note = decodeDemo(in.readUTF()); // Обратное преобразование строки после десериализации
}
private String encodeDemo(String data) {
// Учебное преобразование строки, не шифрование
return new StringBuilder(data).reverse().toString();
}
private String decodeDemo(String data) {
// Обратное преобразование строки
return new StringBuilder(data).reverse().toString();
}
@Override
public String toString() {
return "Name: " + name + ", Age: " + age + ", Note: " + note;
}
// Геттеры и сеттеры (если нужно)
}
- Сериализация и десериализация объекта:
public class Main {
public static void main(String[] args) {
CustomSerializableClass obj = new CustomSerializableClass("Alice", 30, "sampleNote");
// Сериализация
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("customObject.ser"))) {
oos.writeObject(obj);
} catch (IOException e) {
e.printStackTrace();
}
// Десериализация
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("customObject.ser"))) {
CustomSerializableClass deserializedObj = (CustomSerializableClass) ois.readObject();
System.out.println(deserializedObj);
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}