1. 程式人生 > >移動Web開發,資料壓縮,後端壓縮傳輸的json格式資料

移動Web開發,資料壓縮,後端壓縮傳輸的json格式資料

最近做了個移動web應用,java平臺做後臺,後臺查詢的資料結果用json格式傳輸,其中有個頁面,後臺返回的資料量很大,json字串達到了68K,這對於移動裝置的流量和響應速度來說,絕對是個悲劇。

1,未處理前的資料格式為:

{[{"consDept":"A部門","consDeptCode":"001","provinceScheduleVO":[{"projectTypeCode":"DEngineering","percentSchedule":"100","planStartStatus":"2"},{"projectTypeCode":"Main","percentSchedule":"50","planStartStatus":"2"}, ……]},

{"consDept":"B部門","consDeptCode":"002","provinceScheduleVO":[{"projectTypeCode":"DEngineering","percentSchedule":"100","planStartStatus":"1"},{"projectTypeCode":"Main","percentSchedule":"0","planStartStatus":"1"}, ……]}, …… ]};

字串大小為68K.

2,很明顯,字串越長,體積越大,因為是陣列形式,相同的屬性名稱會重複很多次,通過減短屬性名稱,應該能降低不少體積。

比如,把consDept屬性名改成a,consDeptCode屬性名改成b,把projectTypeCode屬性名稱改成c, ……  切記不要傳輸前臺不需要的屬性。

處理後的資料格式為:

{[{"a":"A部門","b":"001","VO":[{"c":"DEngineering","d":"100","e":"2"},{"c":"Main","d":"50","e":"2"}, ……]},

{"a":"B部門","b":"002","VO":[{"c":"DEngineering","d":"100","e":"1"},{"c":"Main","d":"0","e":"1"}, ……]}, …… ]};

字串大小變成了25K,效果很明顯。

對於這種陣列形式,如果資料格式相對比較簡單,沒有巢狀的一維陣列,甚至可以改成鍵值對的形式, 比如 “a”:["A部門","B部門","C部門"] ,以減少“a”屬性名稱出現的次數。

 

3,對結果再採用壓縮演算法來壓縮,(此處演示用ZIP或GZIP壓縮)

ZIP壓縮,除了壓縮外,還會歸檔成一個檔案

GZIP壓縮,則只能壓縮。本應用無需歸檔,所以,此處採用GZIP方式壓縮字串。

運用jdk自帶的java.util.zip.GZIPInputStream,java.util.zip.GZIPOutputStream 即可完成壓縮。

處理後的資料格式為:

"{?\u0001°T?U?????5\u003e\u0010?(\r\u0002Ql?\u0018\u0013\u0014±\u0015\u000bH??\u0016\"b??? ?\"_A?\u0019v???è\u001e??×??I?2Op?ss???????\u000
2??????[?\u001bY~\u001f?_y?yn?\r\u0027??B7?\nm?is6\u000eU?èüH}ì7;úVá*?\u0013Q??\u0012re??W\u0016?\u000f??\u0015?à\u0013?|8Bm??-J7q?V?]\u0013u\\\u003dA???\u001frB??\u000f????\u0005?\u0016?\u0012|T?N??\u0012?p????\u0004Ué[??^?·\u003c???9T?\u001au\n?eE???_\u001fJ?O}……

字串大小變成了1.4K,節省了不少空間。

附上GZIP壓縮java程式碼:

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
 
/**
 * Gzip 壓縮字串
 */
public class GZIP { 
 /**
  * 字串的壓縮
  * @param str 待壓縮的字串
  * @return 返回壓縮後的字串
  * @throws IOException
  */
 public static String compress(String str) throws IOException {
     if (null == str || str.length() <= 0) {
         return str;
     }
     // 建立一個新的輸出流
     ByteArrayOutputStream out = new ByteArrayOutputStream();
     // 使用預設緩衝區大小建立新的輸出流
     GZIPOutputStream gzip = new GZIPOutputStream(out);
     // 將位元組寫入此輸出流
     gzip.write(str.getBytes("utf-8"));  //因為後臺預設字符集有可能是GBK字符集,所以此處需指定一個字符集
     gzip.close();
     // 使用指定的 charsetName,通過解碼位元組將緩衝區內容轉換為字串
     return out.toString("ISO-8859-1");
 }
 
 /**
  * 字串的解壓
  * @param str 對字串解壓
  * @return 返回解壓縮後的字串
  * @throws IOException
  */
public static String unCompress(String str) throws IOException {
     if (null == str || str.length() <= 0) {
         return str;
     }
     // 建立一個新的輸出流
     ByteArrayOutputStream out = new ByteArrayOutputStream();
     // 建立一個 ByteArrayInputStream,使用 buf 作為其緩衝區陣列
     ByteArrayInputStream in = new ByteArrayInputStream(str.getBytes("ISO-8859-1"));
     // 使用預設緩衝區大小建立新的輸入流
     GZIPInputStream gzip = new GZIPInputStream(in);
     byte[] buffer = new byte[256];
     int n = 0;

     // 將未壓縮資料讀入位元組陣列
     while ((n = gzip.read(buffer)) >= 0){
           out.write(buffer, 0, n);
     }
     // 使用指定的 charsetName,通過解碼位元組將緩衝區內容轉換為字串 
     return out.toString("utf-8"); 
     }
}