This example shows how to use ObjectInputStream to read a serialized object from a file in Java, aka Deserialization.

  public static Object readObjectFromFile(File file) throws IOException, ClassNotFoundException {
      Object result = null;
      try (FileInputStream fis = new FileInputStream(file);
           ObjectInputStream ois = new ObjectInputStream(fis)) {
          result = ois.readObject();
      }
      return result;
  }

  // Convert byte[] to object, with deserialization filter, Java 9
  public static Object convertBytesToObject(byte[] bytes, ObjectInputFilter filter) {
      InputStream is = new ByteArrayInputStream(bytes);
      try (ObjectInputStream ois = new ObjectInputStream(is)) {

          // add filter before readObject
          ois.setObjectInputFilter(filter);

          return ois.readObject();
      } catch (IOException | ClassNotFoundException ioe) {
          ioe.printStackTrace();
      }
      throw new RuntimeException();
  }

Further Reading

Java Serialization and Deserialization examples

1. Read serialized object from a file (ObjectInputStream)

The below example converts a Person object to bytes stream and saves it into a file (Serialization). Later, it reads the bytes stream from the same file and converts it back to the original object (Deserialization).

Person.java

package com.favtuts.io.object;

import java.io.Serializable;
import java.math.BigDecimal;

public class Person implements Serializable {
    
    private static final long serialVersionUID = -1;
    private String name;
    private int age;

    // if transient, JVM ignore this field for serialization
    private transient BigDecimal salary;

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public BigDecimal getSalary() {
        return salary;
    }

    public void setSalary(BigDecimal salary) {
        this.salary = salary;
    }

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

HelloSerializationFile.java

package com.favtuts.io.object;

import java.io.*;
import java.math.BigDecimal;

public class HelloSerializationFile {

    public static void main(String[] args) throws IOException, ClassNotFoundException {

        Person person = new Person("favtuts", 50, new BigDecimal(1000));

        File file = new File("person.bin");

        writeObjectToFile(person, file);

        Person p = (Person) readObjectFromFile(file);

        System.out.println(p);

    }

    // Serialization
    // Save object into a file.
    public static void writeObjectToFile(Person obj, File file) throws IOException {
        try (FileOutputStream fos = new FileOutputStream(file);
             ObjectOutputStream oos = new ObjectOutputStream(fos)) {
            oos.writeObject(obj);
            oos.flush();
        }
    }

    // Deserialization
    // Get object from a file.
    public static Object readObjectFromFile(File file) throws IOException, ClassNotFoundException {
        Object result = null;
        try (FileInputStream fis = new FileInputStream(file);
             ObjectInputStream ois = new ObjectInputStream(fis)) {
            result = ois.readObject();
        }
        return result;
    }

}

2. More Deserialization examples

  // Deserialization
  // Get object from a file.
  public static Person readObject(File file) throws IOException, ClassNotFoundException {
      Person result = null;
      try (FileInputStream fis = new FileInputStream(file);
           ObjectInputStream ois = new ObjectInputStream(fis)) {
          result = (Person) ois.readObject();
      }
      return result;
  }

  // Deserialization
  // generic example
  @SuppressWarnings("unchecked")
  public static <T> T readObject(InputStream is, Class<T> anyClass)
      throws IOException, ClassNotFoundException {
      T result = null;
      try (ObjectInputStream ois = new ObjectInputStream(is)) {
          result = (T) ois.readObject();
      }
      return result;
  }

  // Deserialization
  // Convert object to byte[]
  public static byte[] convertObjectToBytes(Object obj) {
      ByteArrayOutputStream boas = new ByteArrayOutputStream();
      try (ObjectOutputStream ois = new ObjectOutputStream(boas)) {
          ois.writeObject(obj);
          return boas.toByteArray();
      } catch (IOException ioe) {
          ioe.printStackTrace();
      }
      throw new RuntimeException();
  }

3. Java 9 Deserialization filters

In Java, deserialization from untrusted byte streams is extremely dangerous. So, Java 9 introduced deserialization filters to filter the incoming serialization data.

Person2.java

package com.favtuts.io.object;

import java.math.BigDecimal;

public class Person2 extends Person {
    private String address;

    public Person2(String name, int age, BigDecimal salary, String address) {
        super(name, age, salary);
        this.address = address;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }
}

The below example shows how to use deserialization filters to only deserializing objects from com.favtuts.io.object.Person and java.base/*. Others all reject !*.

HelloDeserializationFilter.java

package com.favtuts.io.object;

import java.io.*;
import java.math.BigDecimal;

public class HelloDeserializationFilter {
    public static void main(String[] args) {
        // this ok
        // Person person = new Person("favtuts", 40, new BigDecimal(900));

        // reject this Person2, only allow Person class
        Person2 person = new Person2("favtuts", 40, new BigDecimal(900), "test");

        byte[] bytes = convertObjectToBytes(person);

        // only allow to deserialize com.favtuts.io.object.Person and java.base/*
        // !* reject all
        ObjectInputFilter filter = ObjectInputFilter.Config.createFilter(
                "com.favtuts.io.object.Person;java.base/*;!*");

        Person p = (Person) convertBytesToObject(bytes, filter);

        System.out.println(p);
    }

    // Convert object to byte[]
    public static byte[] convertObjectToBytes(Object obj) {
        ByteArrayOutputStream boas = new ByteArrayOutputStream();
        try (ObjectOutputStream ois = new ObjectOutputStream(boas)) {
            ois.writeObject(obj);
            return boas.toByteArray();
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }
        throw new RuntimeException();
    }

    // Convert byte[] to object, with filter
    public static Object convertBytesToObject(byte[] bytes, ObjectInputFilter filter) {
        InputStream is = new ByteArrayInputStream(bytes);
        try (ObjectInputStream ois = new ObjectInputStream(is)) {

            // add filter before readObject
            ois.setObjectInputFilter(filter);

            return ois.readObject();
        } catch (IOException | ClassNotFoundException ioe) {
            ioe.printStackTrace();
        }
        throw new RuntimeException();
    }
}

Output

java.io.InvalidClassException: filter status: REJECTED
        at java.base/java.io.ObjectInputStream.filterCheck(ObjectInputStream.java:1356)
        at java.base/java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:2007)
        at java.base/java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1864)
        at java.base/java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2195)
        at java.base/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1681)
        at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:493)
        at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:451)
        at com.favtuts.io.object.HelloDeserializationFilter.convertBytesToObject(HelloDeserializationFilter.java:52)
        at com.favtuts.io.object.HelloDeserializationFilter.main(HelloDeserializationFilter.java:27)
Exception in thread "main" java.lang.RuntimeException
        at com.favtuts.io.object.HelloDeserializationFilter.convertBytesToObject(HelloDeserializationFilter.java:56)
        at com.favtuts.io.object.HelloDeserializationFilter.main(HelloDeserializationFilter.java:27)

Further Reading

Download Source Code

$ git clone https://github.com/favtuts/java-core-tutorials-examples

$ cd java-io/object

References

Leave a Reply

Your email address will not be published. Required fields are marked *