Java and J2EE Tutorials, Jsp and Servlet Tutorials, Spring MVC, Solr, XML, JSON Examples, Hibernate & Struts 2 Hello World projects



Saturday, 7 December 2013

Serialization and Deserialization in Java - Example

Java serialization is a mechanism to persist Java objects in a ordered or sequenced form of bytes, it includes objects’s data and object’s type and type of data that is stored in it as well.

Serialization is the mechanism of translating Java object's values and states to bytes to send it over network or to save it on file and disks. On other hand Deserialization is the processs of converting byte code to corresponding java objects.


Serialization and Deserialization in Java

Java serialization API provides mechanism to write an object into streams, disks, db’s or something…. so that the object can be transported over network or can be stored somewhere and can be rebuild again when needed. Getting serialized object again called deserialization.


Need of Serialization

Serialization comes into picture when we need to send an object(not text) over network or store in a file so that the object can be rebuild again when needed. But the network infrastructure and hard disks does not understand java, what they understand are bytes only, and this is what serialization does. It converts java object to bytes and bytes to java object again.


How to Serialize an object in java

All steps are included in the image showing below, lets implement all those steps of serialization one by one to persist a java object to a specified file.



Class to be serialized – Student.java

A class must implement Serializable interface in order to be serialized, this is a marker interface that does not contain any method in it.
package com.beingjavaguys.core;

import java.io.Serializable;

/**
 * @author Nagesh Chauhan
 * 
 */
@SuppressWarnings("serial")
public class Student implements Serializable {

 private static final long serialVersionUID = 1L;

 private int id;
 private String name;

 public int getId() {
  return id;
 }

 public void setId(int id) {
  this.id = id;
 }

 public String getName() {
  return name;
 }

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

}


Serialization Implementation – SimpleSerImpl.java

Here is code for serialization of java objects, we just need to get an FileOutputStream object from the five we want to persist the object and pass this to ObjectOutputStream's object's constructor. Method writeObject() is used to get bytes from java object and pass them to output stream.
package com.beingjavaguys.core;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

/**
 * @author Nagesh Chauhan
 * 
 */
public class SimpleSerImpl {
 public static void main(String args[]) {

  /*
   * Assigning values to Student classes
   */
  Student student = new Student();
  student.setId(1);
  student.setName("Nagesh Chauhan");

  /*
   * Serializing Student class
   */
  try {
   FileOutputStream fileOutputStream = new FileOutputStream(
     "serialobject.ser");
   ObjectOutputStream objectOutputStream = new ObjectOutputStream(
     fileOutputStream);
   objectOutputStream.writeObject(student);

  } catch (FileNotFoundException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (IOException ioe) {
   // TODO Auto-generated catch block
   ioe.printStackTrace();
  }

 }
}


How to Deserialize an object in java

All steps are included in the image showing below, lets implement all those steps of deserialization one by one to get java object back from the file.



Deserialization Implementation – SimpleSerImpl.java

Here is code for deserialization of java objects, we just need to get an FileInputStream object from the file that contains object's bytes and pass this to ObjectInputStream's object's constructor. Method readObject() returns an object whose bytes are being read from the file.
package com.beingjavaguys.core;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;

/**
 * @author Nagesh Chauhan
 * 
 */
public class SimpleSerImpl {
 public static void main(String args[]) {

  /*
   * Deerializing Student class
   */
  Student studentOut = null;

  try {
   FileInputStream fileInputStream = new FileInputStream(
     "serialobject.ser");
   ObjectInputStream inputStream = new ObjectInputStream(
     fileInputStream);
   studentOut = (Student) inputStream.readObject();
  } catch (FileNotFoundException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (IOException ioe) {
   // TODO Auto-generated catch block
   ioe.printStackTrace();
  } catch (ClassNotFoundException cnf) {
   // TODO Auto-generated catch block
   cnf.printStackTrace();
  }

  /*
   * Printing values from deserialized object
   */
  System.out.println("Deserailization of Student's object :");
  System.out.println("ID: " + studentOut.getId());
  System.out.println("Name: " + studentOut.getName());

 }
}
Output: Here is expected output, printing values for deserialized object.



Here we are done with Serialization and Deserialization of a simple objcte in java, but in real world applications many other situation may occur. Lets look a little deep in serialization in different scenarios.


What if the serialized object has a reference to another object

In case the object we are going to serialize has some reference to other object, then what would happen ?In this case three possible conditions can arise.


CASE 1: If the referenced class implements Serializable.

In case we have a reference to another object and the referenced class also implements Serializable, that the referenced class will be automatically serialized. In the example below, we have a Employee class that contains EmployeeAddress’s reference in it, in this case the both classes are implementing Serializable interface so both will be serialized.

Class to be serialized - Employee.java

package com.beingjavaguys.core;

import java.io.Serializable;
/**
 * @author Nagesh Chauhan
 * 
 */
public class Employee implements Serializable {
 private int empId;
 private String empName;
 private EmployeeAddress employeeAddress;

 public int getEmpId() {
  return empId;
 }

 public void setEmpId(int empId) {
  this.empId = empId;
 }

 public String getEmpName() {
  return empName;
 }

 public void setEmpName(String empName) {
  this.empName = empName;
 }

 public EmployeeAddress getEmployeeAddress() {
  return employeeAddress;
 }

 public void setEmployeeAddress(EmployeeAddress employeeAddress) {
  this.employeeAddress = employeeAddress;
 }

}


Referenced Class – EmployeeAddress

Here is a simple referenced class 'EmployeeAddress ' this class is being referenced by 'Employee' and implements serializable interface. This class w'll be serialized along with Employee.
package com.beingjavaguys.core;

import java.io.Serializable;
/**
 * @author Nagesh Chauhan
 * 
 */
public class EmployeeAddress implements Serializable {
 
 private String street;
 private String city;
 private String state;
 private String country;
 
 public String getStreet() {
  return street;
 }
 public void setStreet(String street) {
  this.street = street;
 }
 public String getCity() {
  return city;
 }
 public void setCity(String city) {
  this.city = city;
 }
 public String getState() {
  return state;
 }
 public void setState(String state) {
  this.state = state;
 }
 public String getCountry() {
  return country;
 }
 public void setCountry(String country) {
  this.country = country;
 }
 
}


Serialization and De-serialization Implementation


Here is code for serialization and deserialization of java object with a reference to another serializable object. See the implementation below:
package com.beingjavaguys.core;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
/**
 * @author Nagesh Chauhan
 * 
 */
public class ReferenceSerImpl {
 public static void main(String args[]) {

  /*
   * Assigning values to Employee and EmployeeAdress classes
   */
  Employee emp = new Employee();
  emp.setEmpId(1);
  emp.setEmpName("Nagesh Chauhan");

  EmployeeAddress employeeAddress = new EmployeeAddress();
  employeeAddress.setStreet("Sec-44");
  employeeAddress.setCity("Delhi");
  employeeAddress.setState("Delhi");
  employeeAddress.setCountry("India");

  emp.setEmployeeAddress(employeeAddress);

  /*
   * Serializing Employee class, referenced class EmployeeAdress will be
   * serialized bydefault, unless the referenced class variable is not
   * declared transient
   */
  try {
   FileOutputStream fileOutputStream = new FileOutputStream(
     "serialObject.ser");
   ObjectOutputStream objectOutputStream = new ObjectOutputStream(
     fileOutputStream);
   objectOutputStream.writeObject(emp);

  } catch (FileNotFoundException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (IOException ioe) {
   // TODO Auto-generated catch block
   ioe.printStackTrace();
  }

  /*
   * Deserializing Employee class, referenced class EmployeeAdress will be
   * deserialized bydefault, unless the referenced class variable is not
   * declared transient
   */
  Employee empout = null;

  try {
   FileInputStream fileInputStream = new FileInputStream(
     "serialobject.ser");
   ObjectInputStream inputStream = new ObjectInputStream(
     fileInputStream);
   empout = (Employee) inputStream.readObject();

  } catch (FileNotFoundException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (IOException ioe) {
   // TODO Auto-generated catch block
   ioe.printStackTrace();
  } catch (ClassNotFoundException cnf) {
   // TODO Auto-generated catch block
   cnf.printStackTrace();
  }

  /*
   * Printing values from deserialized object
   */
  System.out.println("Deserailization of Employee and Address :");
  System.out.println("Emp ID: " + empout.getEmpId());
  System.out.println("Emp Name: " + empout.getEmpName());
  System.out.println("Emp Address Street: "
    + empout.getEmployeeAddress().getStreet());
  System.out.println("Emp Address City: "
    + empout.getEmployeeAddress().getCity());
  System.out.println("Emp Address State: "
    + empout.getEmployeeAddress().getState());
  System.out.println("Emp Address Country: "
    + empout.getEmployeeAddress().getCountry());

 }
}
Output: Here is expected output, printing values for deserialized object.


In case the reference class does not implement Serializable it’s variable must be declared transient.


CASE 2: If the referenced class does not implements Serializable but its reference variable is transient.

In case the referenced class EmployeeAddress does not implement Serializable interface, than there will be runtime error in serializing Employee class. To avoid the error just make EmployeeAddress’s reference variable transient.

Transient EmployeeAddress employeeAddress; In this case when we will deserialize Employee class, there will be a null value for EmployeeAddress reference.


CASE 3: If the referenced class can not implement Serializable interface and we still want to persist its states.

In the above two cases we saw, if a reference variable is there either the referenced class must be serializable or the reference variable must be declared transient. Now the question arises, is it possible to persist states of a referenced class even if the class is not serializable and its reference variable is declared transient. Yes, This is possible !

In that case, Java serialization provides a mechnism such that if you have private methods with particular signature then they will get called during serialization and deserialization so we will override writeObject and readObject method of Employee class and they will be called during serialization and deserialization of Employee object.

Object To Serialize – Employee.java

package com.beingjavaguys.com;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
/**
 * @author Nagesh Chauhan
 * 
 */
public class Employee implements Serializable {
 private static final long serialVersionUID = 1L;
 private int empId;
 private String empName;
 transient private EmployeeAddress employeeAddress;

 public int getEmpId() {
  return empId;
 }

 public void setEmpId(int empId) {
  this.empId = empId;
 }

 public String getEmpName() {
  return empName;
 }

 public void setEmpName(String empName) {
  this.empName = empName;
 }

 public EmployeeAddress getEmployeeAddress() {
  return employeeAddress;
 }

 public void setEmployeeAddress(EmployeeAddress employeeAddress) {
  this.employeeAddress = employeeAddress;
 }

 private void writeObject(ObjectOutputStream ous) throws IOException,
   ClassNotFoundException {
  try {
   ous.defaultWriteObject();
   ous.writeObject(employeeAddress.getStreet());
   ous.writeObject(employeeAddress.getCity());
   ous.writeObject(employeeAddress.getState());
   ous.writeObject(employeeAddress.getCountry());

  } catch (Exception e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
 }

 private void readObject(ObjectInputStream ois) throws IOException,
   ClassNotFoundException {
  try {
   ois.defaultReadObject();
   employeeAddress = new EmployeeAddress((String) ois.readObject(),
     (String) ois.readObject(), (String) ois.readObject(),
     (String) ois.readObject());
  } catch (ClassNotFoundException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (Exception e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }

 }

}


Reference Object Without Implementing Serializable – EmployeeAddress.java

Here is a simple referenced class 'EmployeeAddress ' this class is being referenced by 'Employee' and does not implements serializable interface.
package com.beingjavaguys.com;

/**
 * @author Nagesh Chauhan
 * 
 */
public class EmployeeAddress{
 
 private String street;
 private String city;
 private String state;
 private String country;
 
 EmployeeAddress(String street, String city, String state, String country){
  super(); 
  this.street = street;
  this.city = city;
  this.state = state;
  this.country = country;
 }
 
 public String getStreet() {
  return street;
 }
 public void setStreet(String street) {
  this.street = street;
 }
 public String getCity() {
  return city;
 }
 public void setCity(String city) {
  this.city = city;
 }
 public String getState() {
  return state;
 }
 public void setState(String state) {
  this.state = state;
 }
 public String getCountry() {
  return country;
 }
 public void setCountry(String country) {
  this.country = country;
 }
 
}


Implementation – Serialization And Deserialization

Here is code for serialization and deserialization of java object with a reference to another non serializable object. See the implementation below:
package com.beingjavaguys.com;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
/**
 * @author Nagesh Chauhan
 * 
 */
public class ReferenceSerImpl {
 public static void main(String args[]) {

  /*
   * Assigning values to Employee and EmployeeAdress classes
   */
  Employee emp = new Employee();
  emp.setEmpId(1);
  emp.setEmpName("Nagesh Chauhan");

  EmployeeAddress employeeAddress = new EmployeeAddress("Sec-44","Delhi","Delhi","India");
//  employeeAddress.setStreet("Sec-44");
//  employeeAddress.setCity("Delhi");
//  employeeAddress.setState("Delhi");
//  employeeAddress.setCountry("India");
//
  emp.setEmployeeAddress(employeeAddress);

  /*
   * Serializing Employee class, referenced class EmployeeAdress will be
   * serialized bydefault, unless the referenced class variable is not
   * declared transient
   */
  try {
   FileOutputStream fileOutputStream = new FileOutputStream(
     "serialObject.ser");
   ObjectOutputStream objectOutputStream = new ObjectOutputStream(
     fileOutputStream);
   objectOutputStream.writeObject(emp);

  } catch (FileNotFoundException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (IOException ioe) {
   // TODO Auto-generated catch block
   ioe.printStackTrace();
  }

  /*
   * Deserializing Employee class, referenced class EmployeeAdress will be
   * deserialized bydefault, unless the referenced class variable is not
   * declared transient
   */
  Employee empout = null;

  try {
   FileInputStream fileInputStream = new FileInputStream(
     "serialobject.ser");
   ObjectInputStream inputStream = new ObjectInputStream(
     fileInputStream);
   empout = (Employee) inputStream.readObject();

  } catch (FileNotFoundException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (IOException ioe) {
   // TODO Auto-generated catch block
   ioe.printStackTrace();
  } catch (ClassNotFoundException cnf) {
   // TODO Auto-generated catch block
   cnf.printStackTrace();
  }

  /*
   * Printing values from deserialized object
   */
  System.out.println("Deserailization of Employee and Address :");
  System.out.println("Emp ID: " + empout.getEmpId());
  System.out.println("Emp Name: " + empout.getEmpName());
  System.out.println("Emp Address Street: "
    + empout.getEmployeeAddress().getStreet());
  System.out.println("Emp Address City: "
    + empout.getEmployeeAddress().getCity());
  System.out.println("Emp Address State: "
    + empout.getEmployeeAddress().getState());
  System.out.println("Emp Address Country: "
    + empout.getEmployeeAddress().getCountry());

 }
}
Output: Here is expected output, printing values for deserialized object.




Here we are done with 'Serialization and Deserialization in Java'. In our upcoming blogs we will see more about Java Programming and other opensource technologies.








Thanks for reading !
Being Java Guys Team




1 comment:

  1. Superb note...I don't want more than this from serialisation.........

    ReplyDelete

Like Us on Facebook


Like Us On Google+



Contact

Email: neel4soft@gmail.com
Skype: neel4soft