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; } }
沒有留言 :
張貼留言