Java 可以使用序列化/反序列化的技術將物件實體 (Object Instance)
轉成位元組格式資料 (通常用 byte array 表示) 再轉回來,
方便我們將物件實體保持起來等之後將其還原回物件實體,
或將其轉文字等用 http request 送給其他 server 並在server 端接收並還原。
Note:
物件必須要實作 Serializable 介面才能被序列化。以下程式碼展示了兩個範例,
分別為將物件以檔案的方式
及以文字的方式進行序列化/反序列化。
而不管是將物件序列化成何種型式(例如檔案或文字),
概念都是一樣的,就是以物件被序列化成位元組格式
及將位元組反序列化回物件。
需要注意的是,如果想將物件序列化成文字 (String) 的話,
因為位元組轉成文字後,有可能會因為編碼等問題轉不回原來的位元組資料,
這時可先將位元組資料用例如 Base64 編碼得到字串來當做序列化後的字串保存起來,
之後要反序列化回物件時,把字串用 Base64 解碼成位元組格式,
再將位元組格式的資料反序列化回物件即可。
以下為程式碼範例 (jdk-11):
先建一個簡單的測試用 Class, Person.java:
Person.java:
package myTest;
import java.io.Serializable;
public class Person implements Serializable{
private static final long serialVersionUID = 1L;
private String name;
public Person(String name) {
this.name = name;
}
public void sayHello() {
System.out.println("Hello, I'm " + name + ".");
}
}
再來是序列化/反序列化的程式碼:
TestObjectSerialize.java:
package myTest;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Base64;
public class TestObjectSerialize {
public static void main(String[] args) {
Person person = new Person("Hugo");
person.sayHello(); //Hello, I'm Hugo.
writeObjectToFile(person, "D:\\MyClass");
Person deSerializedObject = readObjectFromFile(Person.class, "D:\\MyClass");
deSerializedObject.sayHello(); //Hello, I'm Hugo.
String serializedObjectString = writeObjectToString(person);
Person deSerializedObject2 = readObjectFromString(Person.class, serializedObjectString);
deSerializedObject2.sayHello(); //Hello, I'm Hugo.
System.out.println("Done");
}
//----- Serialize/Desrialize Object through file -----//
public static <T> void writeObjectToFile(T object, String filePath){
try (FileOutputStream fileOutputStream = new FileOutputStream(filePath);
ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);){
objectOutputStream.writeObject(object);
}catch(IOException e) {
e.printStackTrace();
}
}
public static <T> T readObjectFromFile(Class<T> clazz, String filePath){
T deserializedObject = null;
try (
FileInputStream fileInputStream = new FileInputStream(filePath);
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
){
deserializedObject = (T) objectInputStream.readObject();
}catch(IOException | ClassNotFoundException e) {
e.printStackTrace();
}
return deserializedObject;
}
//----- Serialize/Desrialize Object through String -----//
//Because Object can be serilaized to String
//, the String can stored in anywhere or be transfer to other server
//and be deserialized to original Object from String.
//Notice: After serializing Object to Byte Array, you should use some way like Base64Encoding to
//encode the Byte Array to String,
//because the String you got directly from Byte Array might not be transfered to original Byte Array.
public static <T> String writeObjectToString(T object){
String serializedObjectString = "";
try (
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
){
objectOutputStream.writeObject(object);
serializedObjectString = new String(Base64.getEncoder().encode(byteArrayOutputStream.toByteArray()), "UTF-8");
} catch (IOException e) {
e.printStackTrace();
}
return serializedObjectString;
}
public static <T> T readObjectFromString(Class<T> clazz, String serializedObjectString){
T deserializedObject = null;
try (
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(Base64.getDecoder().decode(serializedObjectString.getBytes("UTF-8")));
ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
){
deserializedObject = (T) objectInputStream.readObject();
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
return deserializedObject;
}
}
沒有留言 :
張貼留言