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
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