Serialization technique (a) Java Serializable usage scenarios

Serialization technique (a) Java Serializable usage scenarios

1. Java serialization and deserialization (a) scene using Serializable
Serializable 2. Java source code analysis serialization and deserialization (II) --1

Java objects serialized as binary files of Java serialization is Java technology series technology in a more important technical point, in most cases, developers only need to know the sequence of the class needs to implement Serializable interface, use ObjectInputStream and ObjectOutputStream read and write the object.

The paper will introduce some situations, such as the order of the following list.

  1. Serialization issue of ID
  2. Static variables serialization
  3. Serialization parent class and Transient keyword
  4. To encrypt sensitive fields
  5. The sequence of stored rules

1. The most simple to use: Serializable Interface

Context: the Java serialization is simple to use, you can implement the Serializable interface, the actual processing of the marker interface by ObjectOutputStream, ObjectInputStream complete.

Code-1. Java Serialization Serializable interface

@Test
public void testSerializable() throws IOException, ClassNotFoundException {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ObjectOutputStream oos = new ObjectOutputStream(baos);

    User user1 = new User();
    user1.setName("binarylei");
    oos.writeObject(user1);
    byte[] bytes = baos.toByteArray();
    System.out.println(bytes.length);               // length=89

    ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
    ObjectInputStream ois = new ObjectInputStream(bais);
    User user2 = (User) ois.readObject();
    Assert.assertEquals(user1.getName(), user2.getName());  // 反序列化后保存了 User.name 信息
    Assert.assertNotEquals(user1, user2);                   // 反序列化后不是同一个对象

    oos.close();
    ois.close();
}
class User implements Serializable {
    private String name;
    // getter setter
}

Summary: If you do not implement Serializable what will happen then? If the User does not implement Serializable directly NotSerializableException serialization throws an exception.

java.io.NotSerializableException: com.github.binarylei.io.User
  at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)
  at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)

2. The problem of serialization ID

Situation: two clients A and B try to pass through the target data network, A terminal sequence of the object C and then passed into binary data B, B deserialization C. to give

Problems: C full path of the object class is assumed to com.github.binarylei.User, the terminals A and B have such a class file, the function code is exactly the same. Also implement Serializable interface, but deserialization always fails.

Resolution: The virtual machine is allowed to de-serialization, depends not only on the class path and function codes match, a very important point is whether the two classes of serialized ID is consistent (that is, private static final long serialVersionUID = 1L) . Code-1, although the two classes of function code identical, but the sequence of the ID, and will not they each serialization and deserialization.

Code-2. A Contrast same function code of different sequences of ID

public class User implements Serializable { 
    private static final long serialVersionUID = 1L; 
    private String name;
} 
 
public class User implements Serializable { 
    private static final long serialVersionUID = 2L;  
    private String name; 
}

3. static field is not serialized

Storing static variables are not serialized, because the sequence of the object's state is saved, the static state variable belonging to the class, so the sequence of static variables are not saved.

Code-3. Static fields are not serialized

class User implements Serializable {
    public static String staticVar;  // 不会序列化
    private String name;
}

4. Mask field: transient

There are two key transient features:

  1. If you do not want to let a member of the object to be serialized can add keywords transient modification in the definition of it, so, it will not be serialized when the object is serialized.

  2. transient modified members after deserialization given a default value, which is zero or null. Following after deserialization User password = null.

Code-4. Rhetorical transient fields are not serialized

class User implements Serializable {
    public static String staticVar;   // 不会序列化
    public String name;
    public transient String password; // 不会序列化
}

The sequence of the parent class

Context: a subclass implements Serializable interface, its parent class does not implement Serializable interface, the sequence of the sub-class object, then the output value of a variable of the parent class definition after deserialization, the value of the variable and serializing different values.

Solution: To be the parent object serialization, we need to let the parent class also implement the Serializable interface. If the parent does not come true, we need to have a default no-argument constructor. When the parent class does not implement Serializable interface, the virtual machine is a child of the parent object will not be serialized, and construct a Java object must have a parent object, only, de-serialization is no exception. Therefore deserialization, the parent object in order to construct, not only calling the parent class constructor parameter as the default parent object. Thus, when we take the parent variable value, its value is not call the parent class constructor parameter values. If you consider the circumstances of this sequence, no-argument constructor initialize variables in the parent class, otherwise, the parent class variable values are default values declared as int type of default is 0, string type of default It is null.

6. encrypted sensitive field

Scenario: the server to the client object transmission sequence data, there are some object data is sensitive, such as password string, in the hope password field during serialization, encrypted, and if the client has the decryption key only when the client is deserialized, the password can only be read, so you can guarantee a certain degree of safety data serialized objects.

Solution: In the serialization process, the virtual machine tries to call the object class of writeObject and readObject method, user-serialization and de-serialization defined, if there is no such method, called by default is the ObjectOutputStream defaultWriteObject method and of ObjectInputStream defaultReadObject method. User-defined writeObject and readObject methods may allow the user to control the sequence of the process, such as can dynamically change the sequence of values in the sequence of the process. Based on this principle, can be used in practical applications, it is used to encrypt sensitive working field, Code-6 shows this process.

Code-6. Cryptographic code field sensitive

private static final long serialVersionUID = 1L;
private String password = "pass";
// 省略 get/set

private void writeObject(ObjectOutputStream out) throws Exception {
   PutField putFields = out.putFields();
   System.out.println("原密码:" + password);
   password = "encryption";//模拟加密
   putFields.put("password", password);
   System.out.println("加密后的密码" + password);
   out.writeFields();
}

private void readObject(ObjectInputStream in) throws Exception  {
       GetField readFields = in.readFields();
       Object object = readFields.get("password", "");
       System.out.println("要解密的字符串:" + object.toString());
       password = "pass";//模拟解密,需要获得本地的密钥
}

public static void main(String[] args) throws Exception {
   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("解密后的字符串:" + t.getPassword());
   oin.close();
}

In the writeObject method in Code-6, the passwords are encrypted, the password to decrypt the readObject, only has a key client, we can parse out the correct password to ensure data security.

7. The sequence of stored rules

Situation: Problems Code Code-7 as shown in FIG.

Code-7. Rules stored code in question

@Test
public void testSave() throws Exception {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ObjectOutputStream oos = new ObjectOutputStream(baos);

    User user1 = new User();
    user1.setName("binarylei");
    oos.writeObject(user1);
    int length1 = baos.toByteArray().length;
    oos.writeObject(user1);
    int length2 = baos.toByteArray().length;
    Assert.assertEquals(5, length2 - length1);  // 同一个对象写两次,长度只增加了 5
    oos.close();

    ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
    ObjectInputStream ois = new ObjectInputStream(bais);
    User user2 = (User) ois.readObject();
    User user3 = (User) ois.readObject();
    Assert.assertEquals(user1.getName(), user2.getName());
    Assert.assertEquals(user2, user3);  // user2和user3是一个对象
    ois.close();
}

Code-7 writes the same object in two files, print out the memory size and storage size of the write-once written twice the target, then deserialize objects from two files, to compare the two objects whether for the same object. The general thinking is twice the write target file size becomes twice the size, deserialization, since the reading from a file, generates two objects, should be equal fishes input false judgment, but in the end the result is true.

We see that when writing an object file a second time only increased by 5 bytes, and the two objects are equal, which is why?

Answer: the Java serialization mechanism in order to save disk space, with specific storage rules, when a file is written to the same object, and the object's content will no longer be stored, but only store a reference to again increase above 5 bytes of storage space is new references and some control information space. Deserialization, recovery reference relationship, so that the list 3 t1 and t2 unique object point, the two are equal, the output true. The storage rule greatly saves storage space.

This article is reproduced to https://www.ibm.com/developerworks/cn/java/j-lo-serial/


The intentions of recording a little bit every day. Perhaps the content is not important, but the habit is very important!

Guess you like

Origin www.cnblogs.com/binarylei/p/10987540.html