Tuesday, 18 June 2019

Serialization | Example of readObject and writeObject in Serialization methods in Java

Java serialization is an automatic process which uses to save the object state and restore it when it required. To save and read the object state took place by using methods defaultWriteObject, defaultReadObject respectively.

In the default mechanism, static field and transient variable are not serialized or deserialized. As an example, if we want to serialize transient variable we need to use readObject and writeObject. Sometimes, we want to change the default Serialization to save the sensitive information in the object and before saving/retrieving we want to encrypt/decrypt it. We can modify the default serialization process readObject and writeObject methods.

There are four methods that we can provide in the class to change the serialization behavior.

1.readObject(ObjectInputStream ois)
If this method is present in the class, ObjectInputStream readObject() method will use this method for reading the object from stream.

2.writeObject(ObjectOutputStream oos)
If this method is present in the class, ObjectOutputStream writeObject() method will use this method for writing the object to stream.

3.Object writeReplace()
If this method is present, then after serialization process this method is called and the object returned is serialized to the stream.

4.Object readResolve()
If this method is present, then after deserialization process, this method is called to return the final object to the caller program. This method is used to implement Singleton pattern with Serialized classes.

All four methods are kept as private so that subclasses can’t override them. They are meant for serialization purpose only and keeping them private avoids any security issue.

import java.io.*;
class Message implements Serializable, ObjectInputValidation {

    private String msg;

    public Message(String msg) {
        this.msg = msg;
    }
    public String getMsg() {
        return msg;
    }
    @Override
    public String toString() {
        return String.format("[ Message object: %s ]", msg);
    }

    private void writeObject(java.io.ObjectOutputStream out) throws IOException {
        System.out.println("Inside writeObject method");
        out.defaultWriteObject();
        out.writeObject(this.getMsg().replace(" ", "@"));
    }

    private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
        System.out.println("Inside readObject method");
        in.registerValidation(this, 0);
        in.defaultReadObject();
        this.msg = (String)in.readObject();
        this.msg = this.getMsg().replace("@", " ");
    }
   
    private Object writeReplace() throws ObjectStreamException {
        System.out.println("Inside writeReplace method");
        return this;
    }

    private Object readResolve() throws ObjectStreamException {
        System.out.println("Inside readResolve method");
        return this;
    }
   
    @Override
    public void validateObject() throws InvalidObjectException {
        System.out.println("Inside validateObject method");
    }
}

public class SerializeMethodsTest {
    /**
     * Factory method creates an instance of the Message object.
     * @return
     */
    private static Message createMsgObject() {
        return new Message("This a message object!");
    }

    /**
     * This method read data from a resource file and deserialize to Java object.
     * @param fileName
     * @param p
     * @return
     */
    private static Message deserializeObjectUtil(String fileName) {
        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(fileName))) {
            return (Message) ois.readObject();
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * Method to store the serialized object to the resource file.
     *
     * @param fileName
     * @param message
     */
    private static void seriliazeObjectUtil(String fileName, Message message) {
        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(fileName))) {
            oos.writeObject(message);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        String fileName = "message.ser";

        // Create Message object.
        Message msg1 = createMsgObject();
        // serialize and store the message object instance in file.
        seriliazeObjectUtil(fileName, msg1);

        // deserialize person object instance from the file.
        Message msg2 = deserializeObjectUtil(fileName);
        System.out.println(msg2);
    }
}

No comments:

Post a Comment

Related Posts Plugin for WordPress, Blogger...