Advanced understanding of "Java" Java serialization

Source: Internet
Author: User
Tags decrypt object serialization

If you only know the object that implements the Serializable interface, you can serialize it to a local file. Then you'd better read the article, which is a further discussion of serialization, with real-world examples of the high-level understanding of serialization, including the problem of parent-class serialization, static variable problems, the effects of transient keywords, and serialization ID issues. In the actual development process of the author, I encountered the problem of serialization, in this article will also share with the reader.

15 Reviews:

Cancrush, Graduate School of Software, Tohoku University

Weijiang, Graduate School of Software, Tohoku University

March 16, 2011

    • Content
Introduction

The Java serialization technology that serializes Java objects into binaries is an important technical point in the Java family of technologies, and in most cases developers need only to understand that the class being serialized needs to implement the Serializable interface, using ObjectInputStream and O Bjectoutputstream to read and write objects. However, in some cases, it is not enough to know this, the article lists some of the real situations I encountered, they are related to the Java serialization, through the analysis of the causes of the situation, so that readers easily remember some of the high-level understanding of Java serialization.

Back to top of page

Article structure

This article will introduce several scenarios, in the order of the following list.

    • Problem with serialization ID
    • Serialization of static variables
    • Serialization of the parent class with the Transient keyword
    • Encrypt sensitive fields
    • Serialization of storage rules

Each part of the list tells a separate context that the reader can view separately.

Back to top of page

Serialization ID Issues

Scenario : Two clients A and B attempt to pass object data over the network, and the A-side serializes object C to binary data and then to B,b to deserialize to get C.

problem : The full class path of the C object is assumed to be com.inout.Test, and there is such a class file on both A and B ends, the function code is exactly the same. The Serializable interface is also implemented, but the deserialization always indicates that it is not successful.

Workaround : Whether the virtual machine allows deserialization depends not only on the class path and function code consistency, but also on whether the serialization IDs of the two classes are consistent (that is, the private static final long Serialversionuid = 1L). In Listing 1, although the functional code of the two classes is exactly the same, but the serialization IDs are different, they cannot serialize and deserialize one another.

Listing 1. Class comparison of different serialization IDs for same function code
Package com.inout;  Import java.io.Serializable;  public class A implements Serializable {  private static final long serialversionuid = 1L;  private String name;  Public String getName ()  {  return name;  }  public void SetName (String name)  {  this.name = name;  }  }  Package com.inout;  Import java.io.Serializable;  public class A implements Serializable {  private static final long serialversionuid = 2L;  private String name;  Public String getName ()  {  return name;  }  public void SetName (String name)  {  this.name = name;  }  }

The serialization ID provides two build strategies under Eclipse, one fixed 1L, one randomly generating a non-repeating long type of data (actually generated using the JDK tool), where there is a recommendation that, if there is no special requirement, it is available with the default 1L, which ensures that the code is consistent When deserialization succeeds. So what does a randomly generated serialization ID do, and sometimes it can be used to restrict the use of certain users by changing the serialization ID.

Feature Use Cases

The reader should have heard of the Façade mode, which provides a unified provider for the application, which is used by client clients in the case program, as shown in Figure 1 of the case program structure.

Figure 1. Case Program Structure

The client side can interact with business logic objects by Façade object. The client's Façade object cannot be generated directly by client, but requires Server-side generation and then serializes the binary object data through the network to client,client responsible for deserializing the Façade object. This mode allows the use of client-side programs to require server-side licensing, while the client side and the server-side Façade Object class need to be consistent. When the server side wants to make a version update, as long as the server-side Façade object class serialization ID is generated again, when the client side deserialization Façade Object will fail, that is, forcing the client side to obtain the latest program from the server side.

Back to top of page

Serialization of static variables

Scenario : View the code in Listing 2.

Listing 2. Static variable serialization problem code
public class Test implements Serializable {private static final long Serialversionuid = 1l;public static int staticvar = 5 ;p ublic static void Main (string[] args) {try {//initial staticvar is 5ObjectOutputStream out = new ObjectOutputStream (New Fileout Putstream ("Result.obj")); Out.writeobject (new Test ()); Out.close ();//modified to 10test.staticvar = 10;objectinputstream after serialization oin = new ObjectInputStream (New FileInputStream ("Result.obj")); Test T = (test) oin.readobject (); Oin.close ();//read again, print new values by T.staticvar System.out.println (T.staticvar);} catch (FileNotFoundException e) {e.printstacktrace ();} catch (IOException e) {e.printstacktrace ();} catch ( ClassNotFoundException e) {e.printstacktrace ();}}}

The Main method in Listing 2, after serializing the object, modifies the value of the static variable, reads the serialized object, and then obtains the value of the static variable and prints it out through the object being read. According to Listing 2, does the SYSTEM.OUT.PRINTLN (t.staticvar) statement output 10 or 5?

The final output is 10, for the incomprehensible reader that the printed Staticvar is obtained from the Read object, it should be the state at the time of the save. The reason for printing 10 is that when serializing, the static variable is not saved, which is easier to understand, the serialization holds the state of the object, the static variable belongs to the state of the class, so the serialization does not save the static variable .

Back to top of page

Serialization of the parent class with the Transient keyword

context : A subclass implements the Serializable interface, and its parent class does not implement the Serializable interface, serializes the subclass object, and then deserializes the value of a variable defined by the parent class, which differs from the numeric value of the serialization.

workaround : To serialize the parent class object, you need to have the parent class implement the Serializable interface as well. If the parent class is not implemented, the default parameterless constructor is required . When the parent class does not implement the Serializable interface, the virtual machine does not serialize the parent object, and the construction of a Java object must have a parent object before it has child objects, and deserialization is no exception. So when deserializing, in order to construct the parent object, you can only call the parent class's parameterless constructor as the default parent object. So when we take the variable value of the parent object, its value is the value after calling the parent class without a parameter constructor. If you consider this serialization situation, the variable is initialized in the parent class parameterless constructor, otherwise the parent class variable value is the default declared value, such as the default for type int is 0,string, which is null by default.

The function of the Transient keyword is to control the serialization of variables, add the keyword before the variable declaration, you can prevent the variable from being serialized into the file, after being deserialized, the value of the Transient variable is set to the initial value, such as the int type is 0, the object type is null.

Feature Use Cases

We are familiar with the use of the Transient keyword can make the field is not serialized, then there is another way? According to the rules of the parent class object serialization, we can extract the fields that do not need to be serialized into the parent class, the subclass implements the Serializable interface, the parent class is not implemented, and according to the parent class serialization rules, the parent class's field data will not be serialized, as shown in the class Figure 2.

Figure 2. Case Program Class diagram

It can be seen that attr1, ATTR2, ATTR3, ATTR5 are not serialized, the advantage of placing in the parent class is that when there is another child class, ATTR1, ATTR2, ATTR3 will still not be serialized, do not repeat the transient, the code is concise.

Back to top of page

Encrypt sensitive fields

Scenario : The server sends serialized object data to the client, some data in the object is sensitive, such as the password string, and so on, in order to encrypt the password field when it is serialized, and if the client owns the decrypted key, the password can be read only when the client is deserialized. This guarantees the data security of the serialized object to a certain extent.

workaround : During serialization, the virtual opportunity attempts to invoke the WriteObject and ReadObject methods in the object class for user-defined serialization and deserialization, and if there is no such method, the default call is ObjectOutputStream Defaultwriteobject method and the Defaultreadobject method of ObjectInputStream. The user-defined WriteObject and ReadObject methods allow the user to control the serialization process, such as the ability to dynamically change the serialized value during serialization. Based on this principle, it can be used in practical applications for cryptographic work of sensitive fields, and listing 3 shows this process.

Listing 3. Static variable serialization problem code
 Private static final Long serialversionuid = 1l;private string password = "Pass";p ublic string GetPassword () {return pass Word;} public void SetPassword (String password) {this.password = password;} private void WriteObject (ObjectOutputStream out) {try {Putfield putfields = Out.putfields (); System.out.println ("Original password:" + password);p Assword = "Encryption";//Analog Encryption Putfields.put ("password", password); SYSTEM.OUT.PRINTLN ("Encrypted password" + password); Out.writefields ();} catch (IOException e) {e.printstacktrace ();}} private void ReadObject (ObjectInputStream in) {try {GetField readfields = In.readfields (); Object object = Readfields.get ( "Password", "" "); System.out.println ("String to Decrypt:" + object.tostring ());p assword = "pass";//impersonation decryption, need to obtain local key} catch (IOException e) { E.printstacktrace ();} catch (ClassNotFoundException e) {e.printstacktrace ();}} public static void Main (string[] args) {try {objectoutputstream out = new ObjectOutputStream (new FileOutputStream ("Result . obj ")); Out.writeobject (new Test ()); Out.close (); OBJECTINPUtstream oin = new ObjectInputStream (New FileInputStream ("Result.obj")); Test T = (test) oin.readobject (); System.out.println ("decrypted string:" + T.getpassword ()); Oin.close ();} catch (FileNotFoundException e) {e.printstacktrace ();} catch (IOException e) {e.printstacktrace ();} catch ( ClassNotFoundException e) {e.printstacktrace ();}}

In the WriteObject method in Listing 3, the password is encrypted, in the ReadObject, the password is decrypted, only the client with the key, can correctly parse out the password, to ensure the security of the data. Perform listing 3 after console output 3 is shown.

Figure 3. Data Encryption Demo

Feature Use Cases

RMI technology is completely based on the Java serialization technology, the server-side interface calls the required parameter objects to the client, they are transmitted through the network to each other. This involves the issue of the safe transmission of RMI. Some sensitive fields, such as user name password (the user needs to transfer the password when logged in), we want to encrypt it, at this time, we can use the method described in this section to encrypt the password on the client, the server side to decrypt, to ensure the security of data transmission.

Back to top of page

Serialization of storage rules

Scenario : The problem code is shown in Listing 4.

Listing 4. Storage Rule Problem Code
ObjectOutputStream out = new ObjectOutputStream (New FileOutputStream ("Result.obj")); Test test = new test ();//Attempt to write the object two times to the file Out.writeobject (test); Out.flush (); System.out.println (New File ("Result.obj"). Length ()); Out.writeobject (test); Out.close (); System.out.println (New File ("Result.obj"). Length ()), ObjectInputStream oin = new ObjectInputStream (new FileInputStream ("Result.obj"));//Read two files sequentially from a file Test T1 = (test) oin.readobject (); Test t2 = (test) oin.readobject (); Oin.close ();//Determine whether two references point to the same object System.out.println (t1 = = t2);

Listing 3 writes a file two times to the same object, prints the storage size after writing the object once, and stores the size after two writes, then deserializes two objects from the file to compare whether the two objects are the same object. The general thinking is that two write to the object, the file size will become twice times the size, deserialization, due to read from the file, generated two objects, the judgment should be equal when the input is false, but the final result is shown in output 4.

Figure 4. Sample program Output

We see that the second time the object is written, the file only adds 5 bytes, and two objects are equal, which is why?

solution : Java serialization mechanism in order to save disk space, with a specific storage rules, when the file is written to the same object, and no longer store the contents of the object, but just another copy of the reference, the above added 5 bytes of storage space is a new reference and some control information space. When deserializing, restores the reference relationship so that T1 and T2 in Listing 3 point to a unique object, both equal and output true. This storage rule greatly saves storage space.

Feature Case Study

View the code in Listing 5.

Listing 5. Case code
ObjectOutputStream out = new ObjectOutputStream (New FileOutputStream ("Result.obj")); Test test = new test (); test.i = 1;out.writeobject (test); Out.flush (); test.i = 2;out.writeobject (test); Out.close (); O Bjectinputstream oin = new ObjectInputStream (New FileInputStream ("Result.obj")); Test T1 = (test) oin.readobject (); Test t2 = (test) oin.readobject (); System.out.println (T1.I); System.out.println (T2.I);

The purpose of Listing 4 is to save the test object two times into the Result.obj file, write once to modify the object property value again for the second time, and then read two objects sequentially from Result.obj, outputting the I property values of the two objects. The purpose of the case code is to want to transfer the object before and after the modification of the state.

As a result, the two output is 1, because the first time the object is written, the second time when trying to write, the virtual machine according to the reference relationship to know that there is already a same object has been written to the file, so only the second write reference, so read, is the first time to save the object. Readers need to pay special attention to this issue when using a file multiple times writeobject.

Back to top of page

Summary

This article through a few specific scenarios, introduced the Java serialization of some advanced knowledge, although advanced, not to say that readers do not understand, I hope to use the situation introduced by the reader to deepen the impression, can more reasonable use of Java serialization technology, in the future development of the road encountered serialization problems, can be timely solution. Due to my limited knowledge, if there are errors in the article, please contact me to criticize.

Http://www.ibm.com/developerworks/cn/java/j-lo-serial/index.html

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.