As we mentioned in the What is Serialization post, we can use Serialization to move data into or out of a data stream.
So let’s take a look at a simple class, and one that we would want to serialize. This is pretty simple, as you’ll see, we’re just going to add an interface to the class definition: Serializable
. To use it we will need to import java.io
.
import java.io.*;
public class BankInfo implements Serializable {
private String accountHolderName;
private String accountNumber;
private transient String SSN;
public BankInfo(String holder, String acct, String SSN) {
this.accountHolderName = holder;
this.accountNumber = acct;
this.SSN = SSN;
}
public String getBankInfo() {
StringBuilder sb = new StringBuilder();
sb.append(this.accountHolderName + "\n");
sb.append("Account #:" + this.accountNumber + "\n");
return sb.toString();
}
public String getPrivateInfo() {
StringBuilder sb = new StringBuilder(getBankInfo());
sb.append("SSN:" + this.SSN + "\n");
return sb.toString();
}
}
With this code example we can see there is getters or setters, yet with the following code example, we can see how to serialize the data to export it. Below we have a function to allow us to write some sample data.
public static void writeData() {
BankInfo bi = new BankInfo("John Smith", "12348765", "11122333");
FileOutputStream fileOut = null;
ObjectOutputStream out = null;
try {
fileOut = new FileOutputStream("bankInfo.ser");
out = new ObjectOutputStream(fileOut);
out.writeObject(bi);
out.close();
fileOut.close();
System.out.printf("Serialized data is saved in bankInfo.ser");
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
After we write it, we’re going to read that data back in and print it out to the screen.
public static void readData() {
BankInfo bi = null;
try {
ObjectInputStream in = new ObjectInputStream(new FileInputStream("bankInfo.ser") );
bi = (BankInfo) in.readObject();
in.close();
System.out.println(bi.getPrivateInfo());
} catch (IOException ioe) {
ioe.printStackTrace();
return;
} catch (ClassNotFoundException cnfe) {
System.out.println("BankInfo class not found");
cnfe.printStackTrace();
return;
} catch( Exception e) {
System.out.println("General Exception:" + e.getMessage());
e.printStackTrace();
}
}
“Hiding” Data from Serialization
When we read the data back in and print it out however, we notice something interesting. The SSN (Social Security Number) is missing. This is because we marked it as transient
in our BankInfo
class. When something is marked as transient, then it will not be saved via Serialization.
private transient String SSN;
This is important for data the might sensitive, (such as credit card numbers or social security numbers) and might need to be encrypted, or data which is constantly changing, and not worth storing.
Serialization of Classes within Classes
So what happens if you have a class within a class, such as needing an address for an Account Holder.
// inside of the BankInfo Class
private Address holderAddress;
Well, if you try to run this, as is, you will get an exception because Address is a class which cannot be serialized. Therefore, you will need to either, serialize it as well, or mark it as transient.
I have opted to make it Serializable, so it’s data can also be stored, as you see below.
public class Address implements Serializable {
private String address1;
private String address2;
private String city;
private String state;
private String zipcode;
/// snip...
}
Notice that all of its data members are also private, but the Serializable can see past them, and still get them.
Now we run the sample app again, and it will load and display the results as we expect.
The SSN still is null, because it is transient, but all other data is there, including in our sub-classes.
So what to do with that Private Data
That is a great question, because we can work with it. Serialization is often a simple way to transmit data over a network connection, and thus is designed to be efficient, but not to keep information safe.
Since it is not designed with security in mind, one would need to think of other options. The J2EE has built in encryption which could be used, as does other libraries, thus allowing you to send encrypted information between locations securely.
Anything considered to be PII (Personally Identifiable Information) needs to have safeguards in place to ensure if there is someone performing a man int he middle attack, or even a copy of files getting out, then you want to ensure that the data is protected.
How to Serialize Data in Java was originally found on Access 2 Learn
One Comment
Comments are closed.