移動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”屬性名稱出現的次數。
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");
}
}