MessagePack之我見


      隨着移動互聯網的發展,網絡編程也就越來越多的被用到,如果是消息傳輸的話,我想大家大部分會采用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字段打包到集合的前面。好了,目前就寫這些吧!我寫的有什么問題,或者大家有什么疑問,請盡管評論。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM