隨着移動互聯網的發展,網絡編程也就越來越多的被用到,如果是消息傳輸的話,我想大家大部分會采用JSON的格式傳輸,也可能采用其它的格式,但是,在這我向大家推薦一種格式MessagePack,http://msgpack.org/ 這是它的官網,其實說白了就是通過第三方根據一定的格式來壓縮數據,然后到server再按照它的那種格式解壓縮。其實我個人感覺挺簡單的(官網上的例子已經很清楚了),但是,在使用的時候會遇到一些想不到的問題。
首先,我還是簡單的給大家介紹一下怎么使用吧!
開始前的准備,需要導入MessagePack的類庫,但是僅僅導入msgpack-*.jar是不夠的,你還需要導入javassist-*.jar文件,因為msgpack會用到后者的類庫。前期的工作准備好后,就可以開始code了,下面是我寫的一個簡單的例子,大家可以先看一下。
1 package org.tech.msgpack; 2 3 import java.io.IOException; 4 import org.msgpack.MessagePack; 5 import org.msgpack.annotation.Message; 6 7 @Message 8 public class Student{ 9 public int sAge = 0; 10 11 public String sName; 12 13 public boolean sHasPhone; 14 15 public static void main(String[] args) throws IOException { 16 Student stu = new Student(); 17 stu.sAge=13; 18 stu.sName="programer"; 19 stu.sHasPhone=true; 20 21 MessagePack pack = new MessagePack(); 22 23 //序列化 24 byte[] bytes = pack.write(stu); 25 26 //反序列化 27 Student s = pack.read(bytes, Student.class); 28 System.out.println("Name: "+s.sName+"\n"+"Age: "+s.sAge+"\n"+"HasPhone: "+ s.sHasPhone); 29 } 30 }
上面的代碼是一種正常的模式,但是,有時會發生這樣的情況,就是你有一部分產品已經發布出去了,但是呢?根據產品的發展,需求發生了很大的變化,需要在原來的Entity上增加一個字段,還要兼容之前發布的產品,這時,你該怎么辦呢?看完下面那段代碼,你大概就明白了。
1 package org.tech.msgpack; 2 3 import java.io.IOException; 4 import org.msgpack.MessagePack; 5 import org.msgpack.annotation.Message; 6 import org.msgpack.annotation.Optional; 7 8 @Message 9 public class ServerStudent { 10 public int sAge = 0; 11 12 public String sName; 13 14 public boolean sHasPhone; 15 16 /** 17 * 在Server端相應的Entity里添加需要的屬性, 但是為了兼容之前的數據,必須加上注解@Optional 18 * Optional的作用是是否有該字段都不會影響MessagePack的正常解壓 19 */ 20 @Optional 21 public double sHeight; 22 23 /** 24 * 該類里並沒有sHeight字段,可以把它看做已經發出去的產品 25 */ 26 @Message 27 static class ClientStudent { 28 29 public int sAge = 0; 30 31 public String sName; 32 33 public boolean sHasPhone; 34 } 35 36 /** 37 * 與目前Server端數據字段相一致的Entity 38 */ 39 @Message 40 static class NewClientStudent { 41 public int sAge = 0; 42 43 public String sName; 44 45 public boolean sHasPhone; 46 47 public double sHeight; 48 } 49 50 public static void main(String[] args) throws IOException { 51 ClientStudent stu = new ClientStudent(); 52 stu.sAge = 13; 53 stu.sName = "programer"; 54 stu.sHasPhone = true; 55 56 NewClientStudent ns = new NewClientStudent(); 57 ns.sAge = 10; 58 ns.sName = "coder"; 59 ns.sHasPhone = false; 60 ns.sHeight = 180; 61 62 MessagePack pack = new MessagePack(); 63 64 // 序列化 65 byte[] bytes = pack.write(stu); 66 byte[] nBytes = pack.write(ns); 67 68 // 反序列化 69 ServerStudent s = pack.read(bytes, ServerStudent.class); 70 ServerStudent ss = pack.read(nBytes, ServerStudent.class); 71 72 System.out.println("之前發布出去的產品: \n" + "Name: " + s.sName + "\n" 73 + "Age: " + s.sAge + "\n" + "HasPhone: " + s.sHasPhone+"\n\n"); 74 System.out.println("目前的產品: \n" + "Name: " + ss.sName + "\n" + "Age: " 75 + ss.sAge + "\n" + "HasPhone: " + ss.sHasPhone + "\n" 76 + "Height: " + ss.sHeight); 77 } 78 79 }
只要在Server端加一個@Optional注解就OK了。這樣雖然可以解決問題,但是,我們在加這個注解的時候需要格外的小心,尤其是加多個@Optional時,最好分開加,因為有時MessagePack也並不知道你少了那個數據。還有就是不要把@Optional字段打包到集合的前面。好了,目前就寫這些吧!我寫的有什么問題,或者大家有什么疑問,請盡管評論。
