將java物件編碼爲位元組陣列寫入檔案,或用於網路傳輸,在讀取檔案或者接受數據的時候,將其再解碼爲java物件。
從而引出Java進行編解碼的目的:
java的序列化(實現Serializable介面)是java編解碼技術中的一種實現方式。java序列化技術有以下缺陷:
因此,遠端服務呼叫(RPC)不直接使用java原生序列化技術。也正是因爲這些原因,衍生了很多編解碼技術和框架。
評價編解碼框架的優劣,我們主要從以下幾點考慮:
Protobuf 全稱 Google Protocol Buffers,它由谷歌開源而來。它將數據結構以.proto 檔案進行描述,通過程式碼生成工具可以生成對應數據結構的 POJO 物件和 Protobuf 相關的方法和屬性。特點:
Protocol Buffers 是一種輕便高效的結構化數據儲存格式,可以用於結構化數據序列化。它很適合做數據儲存或 RPC 數據交換。
Protobuf 在 Github 開源地址:https://github.com/protocolbuffers/protobuf
Protobuf 另一個吸引人的是它的數據描述檔案和程式碼生成機制 機製。利用數據描述檔案對數據結構進行說明,其優點如下:
Thrift 源於 Facebook,在 2007 年 Facebook 將 Thrift 作爲一個開源專案提交給 Apache 基金會。對於當時的 Facebook 來說,創造 Thrift 是爲了解決 Facebook 各系統間大數據量的傳輸通訊以及系統之間語言環境不同需要跨平臺的特性,因此 Thrift 可以支援多種程式語言,如 C++、C#、Cocoa、Erlang、Haskell、Java、Ocami、Perl、PHP、Python、Ruby 和 Smalltalk。
在多種不同的語言之間通訊,Thrift 可以作爲高效能的通訊中介軟體使用,它支援數據(物件)序列化和多種型別的 RPC 服務。Thrift 適用於靜態的數據交換,需要先確定好它的數據結構,當數據結構發生變化時,必須重新編輯 IDL 檔案,生成程式碼和編譯,這一點跟其他 IDL 工具相比可以視爲是 Thrift 的弱項。Thrift 適用於搭建大型數據交換及儲存的通用工具,對於大型系統中的內部數據傳輸,相對於 JSON 和 XML 在效能和傳輸大小上都有明顯的優勢。
與 Protobuf 比較類似的是,Thrift 通過 IDL 描述介面和數據結構定義,它支援 8 種 Java 基本型別、Map、Set 和 List,支援可選和必選定義,功能非常強大。因爲可以定義數據結構中欄位的順序,所以它也可以支援協定的前向相容。
Thrift 支援三種比較典型的編解碼方式:
由於支援二進制壓縮編解碼,Thrift 的編解碼效能表現也相當優異,遠遠超過 Java 序列化和 RMI 等。
JBoss Marshalling 是一個 Java 物件的序列化 API 包,修正了 JDK 自帶的序列化包的很多問題,但又保持跟 java.io.Serializable 介面的相容;同時增加了一些可調的參數和附加的特性,並且這些參數和特性可通過工廠類進行設定。
相比於傳統的 Java 序列化機制 機製,它的優點如下:
相比於前面介紹的兩種編解碼框架,JBoss Marshalling 更多是在 JBoss 內部使用,應用範圍有限。
Marshalling 在 GitHub 開源地址:https://github.com/jboss-remoting/jboss-marshalling
像 JSON,但是更快更小。
MessagePack 是一種高效的二進制序列化格式。它允許在 JSON 等多種語言之間交換數據,但它更快速更小巧。小整數被編碼爲單個位元組,典型的短字串除了字串本身之外只需要一個額外的位元組。MessagePack 支援主流的 50 多種程式語言。
MessagePack Java 模組 GitHub 開源地址:https://github.com/msgpack/msgpack-java
核心壓縮方式官方說明:https://github.com/msgpack/msgpack/blob/master/spec.md
除了上述介紹的編解碼框架和技術之外,比較常用的還有 kryo、hession 和 Json 等。
實際應用中,是否序列化物件進行傳遞以及使用哪種編解碼框架還是需要應該根據需求而定,有時候發送字串也是挺方便的,比如一個 POJO 物件,或者 Map、List 等,可以先使用 Gson、FastJson 等庫將物件序列化爲 Json 字串,然後發送 json 字串數據,接收的時候,再用 Gson、FastJson 反序列化,將 json 字串轉爲物件即可。