天天看點

Java序列化

序列化常見的使用場景是rpc架構的資料傳輸。常見的序列化方式有三種:

(1)java 原生序列化。 

     java 類通過實作 serializable 接口來實作該類對象的序列化,這個接口非常特殊,沒有任何方法,隻起辨別作用。java 序列化保留了對象類的中繼資料(如類、成員變量、繼承類資訊等),以及對象資料等,相容性最好,但不支援跨語言,而且性能一般。實作 eri lizable 接口的類建議設定 serialversionuid 字段值,如果不設定,那麼每次運作時,編譯器會根據類的内部實作 包括類名、接口名、方法和屬性等來自動生成 se rialversionuid 。如果類的源代碼有修改,那麼重新編譯後 serialversion uid的取值可能會發生變化。是以實作 erializable 接口的類一定要顯式地定義serialversion uid 屬性值。修改類時需要根據相容性決定是否修改serialversionuid。

如果是相容更新,請不要修改serialversionuid 字段 避免反序列化失敗。

如果是不相容更新,需要修改serialversionuid 值,避免反序列化混亂。

        使用 java 原生序列化需注意, java 反序歹lj 化時不會調用類的無參構造方法,而是調用 native 方法将成員變量指派為對應類型的初始值。

基于性能及相容性考慮,不推薦使用 java 原生序列化。

( 2 ) hessian序列 化。

      hessian 序列化是一種支援動态類型、跨語言、基于對象傳輸的網絡協定。java 對象序列化的二進制流可以被其他語言

c++、 python )反序列化。hessian 協定具有如下特性:

自描述序列化類型。不依賴外部描述檔案或接口定義用一個位元組表示常用。基礎類型 極大縮短二進制流。

語言無關,支援腳本語言。

協定簡單,比java 原生序列化高效。

      相比hessian 1.0,hessian 2.0 中增加了壓縮編碼,其序列化二進制流大小是 java序列化的50% 序列化耗時是 java 序列化的 30 ,反序列化耗時是

java 反序列化的20%

      hessian 會把複雜對象所有屬性存儲在一個 ma 進行序列化。是以在父類、子類存在同名成員變量的情況下, hessian 序列化時,先序列化子 ,

然後序列化父類,是以反序列化結果會導緻子類同名成員變量被父類的值覆寫。

(3)json序列化。 json ( javascript ect notation )是一種輕量級的資料交換格式。 json 序列化就是将資料對象轉換為 json 字元串。

在序列化過程中抛棄了類型資訊,是以反序列化時隻有提供類型資訊才能準确地反序列化。相比前兩種方式,json 可讀性比較好,友善調試。

        序列化通常會通過網絡傳輸對象 而對象中往往有敏感資料,是以序列化常常成為黑客的攻擊點,攻擊者巧妙地利用反序列化過程構造惡意代碼,

使得程式在反序列化的過程中執行任意代碼。 java 工程中廣泛使用的 pache commons collectionsjackson fastjson 等都出現過反序列化漏洞。

如何防範這種黑客攻擊呢?有些對象的敏感屬性不需要進行序列化傳輸 ,可以加 transient 關鍵字,避免把此屬性資訊轉化為序列化的二進制流。

如果一定要傳遞對象的敏感屬性,可以使用對稱與非對稱加密方式獨立傳輸,再使用某個方法把屬性還原到對象中。應用開發者對序列化要有一定的

安全防範意識 對傳入資料的内容進行校驗或權限控制,及時更新安全漏洞,避免受到攻擊。