Serialization (Part 3) – Customized serialization and Transient Keyword

in some cases, we prefer to exclude a/ some member(s) of a class from being serialized. the way to do that is to use transient keyword in the declaration of that field. below is an example:

Why?

to decrease the space in the serialization process

Customization of serialization

make sure the Type that implement Serializable interface and you want it to be serialized, implement one or both of these two methods:


private void writeObject(ObjectOutputSteam out) throws IOException

private void readObject(ObjectInputSteam in) throws IOException, ClassNotFoundException

we can make them private since these methods could only be used by Serialization system through Reflections, so we don’t want anyone else outside of this scenario call them.

so in my example below,  I have added a new Char field into my type along with implementing these new methods into my User type and then re-ran the same test file that we have before ….


import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

/**
*
* @author Unknown_
*/
public class User implements Serializable {

private static final long serialVersionUID = -607661653725142657L;

private String username, password;
private int securityCode;
private char permissionCode;

public User() {
}

public User(String username, String password) {
this.username = username;
this.password = password;

}

public void updateUsername(String username) {
System.out.println("username's changed to ... " + username);
this.username = username;
}

public void setSecurityCode(int securityCode) {
this.securityCode = securityCode;
}

@Override
public String toString() {
return "Name: " + this.username + " - passwd: " + this.password + " - SecCode: " + this.securityCode + " permissionCode: " + permissionCode;
}

public void showcontent() {
System.out.println("" + this.toString());
}

public void setPermissionCode(char permissionCode) {
this.permissionCode = permissionCode;
}



/**
* customizing the write object process
* @param out
* @throws IOException
*/
private void writeObject(ObjectOutputStream out) throws IOException{

out.defaultWriteObject();
}

private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException{

ObjectInputStream.GetField readFields = in.readFields();
permissionCode = readFields.get("permissionCode", 'u'); // 'u' as undefined, instead of default compiler '\0' NULL
username = (String) readFields.get("username", null);
password = (String) readFields.get("password", null);
securityCode = readFields.get("securityCode", -1);
}

}

and the test scenario class:


 

import com.navid.practice.serialization.banking.User;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
* we have a bank account and we want to save and then reload that into the
* object instance to see how serialization will work.
*
* @author Unknown_
*/
public class TestScenario1 {

/**
* saving objects into a file that is mentioned in the filename argument.
*
* @param u
* @param filename
*/
public static void saveUser(User u, String filename) {

try (ObjectOutputStream out = new ObjectOutputStream(Files.newOutputStream(Paths.get(filename),StandardOpenOption.APPEND))) {

out.writeObject(u);

} catch (IOException ex) {
Logger.getLogger(TestScenario1.class.getName()).log(Level.SEVERE, null, ex);
} catch (Exception ex) {
}
}

/**
* reading the object from the file mentioned as filename.
*
* @param filename
* @return
*/
public static User reloadUser(String filename) {

User u = null;
try (ObjectInputStream in = new ObjectInputStream(Files.newInputStream(Paths.get(filename), StandardOpenOption.READ))) {
u = (User) in.readObject();

} catch (IOException ex) {
Logger.getLogger(TestScenario1.class.getName()).log(Level.SEVERE, null, ex);
} catch (ClassNotFoundException ex) {
Logger.getLogger(TestScenario1.class.getName()).log(Level.SEVERE, null, ex);
}
return u;
}

public static void main(String[] args) {

User u = new User("MyOldUserName", "myPasswd1");
u.setSecurityCode(1200);
u.showcontent();
u.updateUsername("myNewUsername");
u.showcontent();

System.out.println("Saving Object ... ");
saveUser(u, "myAccounts.dat");
System.out.println("Reloading Object ... ");
reloadUser("myAccounts.dat").showcontent();

}

}

output will be something like this …

run:
Name: MyOldUserName - passwd: myPasswd1 - SecCode: 1200 permissionCode: 
username's changed to ... myNewUsername
Name: myNewUsername - passwd: myPasswd1 - SecCode: 1200 permissionCode: 
Saving Object ... 
Reloading Object ... 
Name: myNewUsername - passwd: myPasswd1 - SecCode: 1200 permissionCode: u
BUILD SUCCESSFUL (total time: 0 seconds)

since we didn’t set the default value for that recently added char in out readObject method we defined a default value. so whenever serialization system couldn’t find that field’s value in file, returned us the default value of that.

 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s