基於protostuff的序列化工具類開發
[toc]
基於protostuff的序列化工具類開發
前言
前面在介紹protostuff的基本使用時(可以參考文章protostuff基本使用),都是針對某個類寫的序列化和反序列化方法,顯然這樣不具有通用性,例如在進行遠端過程呼叫時,傳輸的物件並不唯一,這時就需要開發具有通用性的序列化工具類,即不管序列化的物件是什麼型別,都可以使用該工具類進行序列化。下面就來開發這樣的工具類。
基於這個需要,下面會開發兩個序列化工具類,一個是不具有快取功能的SerializationUtil
,一個是具有快取功能的增強版本SerializationUtil2
。
需要注意的是,protostuff序列化工具類的開發需要大量使用到Java泛型的知識,因此在閱讀這些原始碼時應該需要具有一定的泛型知識儲備,否則程式碼閱讀起來會比較難懂,儘管我已經全部加了註釋。
protostuff序列化工具類SerializationUtil
下面直接給出原始碼:
package cn.xpleaf.protostuff.netty.utils;import com.dyuproject.protostuff.LinkedBuffer;import com.dyuproject.protostuff.ProtostuffIOUtil;import com.dyuproject.protostuff.runtime.RuntimeSchema;/** * 序列化工具類,基於Protostuff實現(其基於Google Protobuf實現) * * @author yeyonghao * */public class SerializationUtil { /** * 序列化方法,將物件序列化為位元組陣列(物件 ---> 位元組陣列) * * @param obj * @return */ @SuppressWarnings("unchecked") public staticbyte[] serialize(T obj) { // 獲取泛型物件的型別 Class clazz = (Class ) obj.getClass(); // 建立泛型物件的schema物件 RuntimeSchema schema = RuntimeSchema.createFrom(clazz); // 建立LinkedBuffer物件 LinkedBuffer buffer = LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE); // 序列化 byte[] array = ProtostuffIOUtil.toByteArray(obj, schema, buffer); // 返回序列化物件 return array; } /** * 反序列化方法,將位元組陣列反序列化為物件(位元組陣列 ---> 物件) * * @param data * @param clazz * @return */ public static T deserialize(byte[] data, Class clazz) { // 建立泛型物件的schema物件 RuntimeSchema schema = RuntimeSchema.createFrom(clazz); // 根據schema例項化物件 T message = schema.newMessage(); // 將位元組陣列中的資料反序列化到message物件 ProtostuffIOUtil.mergeFrom(data, message, schema); // 返回反序列化物件 return message; }}
protostuff序列化工具類SerializationUtil2
SerializationUtil的問題在於,每次呼叫序列化方法和反序列化方法時都需要重新生成一個schema物件,所以可以把生成的schema物件儲存起來,在下一次呼叫方法時就不需要重新生成這些schema物件,這樣可以提高序列化和反序列化的效能。
package cn.xpleaf.protostuff.netty.utils;import java.util.Map;import java.util.concurrent.ConcurrentHashMap;import com.dyuproject.protostuff.LinkedBuffer;import com.dyuproject.protostuff.ProtostuffIOUtil;import com.dyuproject.protostuff.runtime.RuntimeSchema;/** * 具備快取功能的序列化工具類,基於Protostuff實現(其基於Google Protobuf實現) * * @author yeyonghao * */public class SerializationUtil2 { // 快取schema物件的map private static Map, RuntimeSchema>> cachedSchema = new ConcurrentHashMap , RuntimeSchema>>(); /** * 根據獲取相應型別的schema方法 * * @param clazz * @return */ @SuppressWarnings({ "unchecked", "unused" }) private RuntimeSchema getSchema(Class clazz) { // 先嚐試從快取schema map中獲取相應型別的schema RuntimeSchema schema = (RuntimeSchema ) cachedSchema.get(clazz); // 如果沒有獲取到對應的schema,則建立一個該型別的schema // 同時將其新增到schema map中 if (schema == null) { schema = RuntimeSchema.createFrom(clazz); if (schema != null) { cachedSchema.put(clazz, schema); } } // 返回schema物件 return schema; } /** * 序列化方法,將物件序列化為位元組陣列(物件 ---> 位元組陣列) * * @param obj * @return */ @SuppressWarnings("unchecked") public static byte[] serialize(T obj) { // 獲取泛型物件的型別 Class clazz = (Class ) obj.getClass(); // 建立泛型物件的schema物件 RuntimeSchema schema = RuntimeSchema.createFrom(clazz); // 建立LinkedBuffer物件 LinkedBuffer buffer = LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE); // 序列化 byte[] array = ProtostuffIOUtil.toByteArray(obj, schema, buffer); // 返回序列化物件 return array; } /** * 反序列化方法,將位元組陣列反序列化為物件(位元組陣列 ---> 物件) * * @param data * @param clazz * @return */ public static T deserialize(byte[] data, Class clazz) { // 建立泛型物件的schema物件 RuntimeSchema schema = RuntimeSchema.createFrom(clazz); // 根據schema例項化物件 T message = schema.newMessage(); // 將位元組陣列中的資料反序列化到message物件 ProtostuffIOUtil.mergeFrom(data, message, schema); // 返回反序列化物件 return message; }}
測試
測試程式碼如下:
package cn.xpleaf.protostuff.netty.utils;import static org.junit.Assert.*;import org.junit.Test;import cn.xpleaf.pojo.User;public class TestUtil { @Test public void testUtil01() throws Exception { User user = new User("xpleaf", 10); System.out.println(user); // 序列化 byte[] array = SerializationUtil.serialize(user); // 反序列化 User user2 = SerializationUtil.deserialize(array, User.class); System.out.println(user2); // 判斷值是否相等 System.out.println(user.toString().equals(user2.toString())); } @Test public void testUtil02() throws Exception { User user = new User("xpleaf", 10); System.out.println(user); // 序列化 byte[] array = SerializationUtil2.serialize(user); // 反序列化 User user2 = SerializationUtil2.deserialize(array, User.class); System.out.println(user2); // 判斷值是否相等 System.out.println(user.toString().equals(user2.toString())); }}
執行testUtil01時的輸出結果如下:
User [name=xpleaf, age=10]User [name=xpleaf, age=10]true
執行testUtil02時的輸出結果如下:
User [name=xpleaf, age=10]User [name=xpleaf, age=10]true
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/2471/viewspace-2813881/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Protostuff開發
- 基於微信開發的一款工具類小程式。
- 《從零開始搭建遊戲伺服器》 序列化工具(最優版Protostuff)遊戲伺服器
- Protocol Buffer序列化Java框架-ProtostuffProtocolJava框架
- jackson、fastjson、kryo、protostuff等序列化工具效能對比ASTJSON
- 基於Docker封裝的開發包工具Docker封裝
- 十大基於Docker的開發工具Docker
- 基於命令列的WINCE驅動開發工具命令列
- 基於 Angular 開發的 紀念日計算工具Angular
- CatiaMagic — 基於MBSE的產品創新和正向開發工具
- 基於Koa.js的微信工具類小記JS
- 基於slf4j的日誌工具類
- 基於node.js的腳手架工具開發經歷Node.js
- 基於jquery+html開發的json格式校驗工具jQueryHTMLJSON
- 一款基於 Java 開發的微信資料分析工具!Java
- Java開發常用的16個工具類Java
- Android開發中常用的工具類Android
- 基於百度翻譯API開發屬於自己的翻譯工具API
- 基於TP3.2和Bootstrap開發的歌詞類網站boot網站
- 基於 Hyperf 開發的商城
- 基於Github的敏捷開發Github敏捷
- 基於TODO的開發方法
- 基於eTS高效開發HarmonyOS課程類應用ASGR
- 關於開發工具的選擇
- 基於HttpClient實現Http訪問工具類HTTPclient
- 基於正則的INI讀寫工具類,支援加密解密加密解密
- 基於WDF的驅動開發
- 開發積累—泛型工具類泛型
- 2.1 基於python開發的資料比對工具--SYDCTOOL介紹Python
- 基於窗體設計器的企業管理軟體開發工具
- Json反序列化物件通用工具類JSON物件
- Protostuff詳解
- 碎閱:一款基於douban及ONE API開發的資訊類AppAPIAPP
- 類似Matlab的Python開發工具spyderMatlabPython
- java實現Excel定製匯出(基於POI的工具類)JavaExcel
- 自己開發的線上視訊下載工具,基於Java多執行緒Java執行緒
- 基於ThinkPHP開發的公司官網PHP
- 基於ThinkPHP開發的好處如下:PHP