星期二, 8月 20, 2013

web service 壓縮回傳大量資料





1.流程
因為web service是以XML傳輸,要傳至client端的內容需先轉String後再傳,但大量資料往往傳沒幾筆就停了,解決方式除了限制傳輸筆數外,尚可在傳輸前將資料壓縮,但壓縮過的資料要能透過HTTP傳輸,就得先以base64編碼再傳。
client端收到之後反向處理,先解base64,解壓縮,再轉成物件。

2.Server端資料壓縮
直接看code吧

public String doZipQuery(String iStr) throws Exception {

//取得多筆的資料或物件
//物件轉XML
String strObj=objToStr(objs);
//壓縮
byte[] bCompress=compress(strObj);
//base64編碼
        String en64= new BASE64Encoder().encode(bCompress);        
        return en64;        
}

// 壓縮
public static byte[] compress(String str) throws IOException {
if (str == null || str.length() == 0) {
     return null;
}
ByteArrayOutputStream out = new ByteArrayOutputStream();
GZIPOutputStream gzip = new GZIPOutputStream(out);
gzip.write(str.getBytes());
gzip.close();
return out.toByteArray();
}


3.client端解壓縮

建立呼叫web service的Proxy

新增web service client

填入web service wsdl的路徑

記得勾選「Define custom mapping for namespace to package」


建立Proxy時class名稱的對照改一下,不然很長會有點困擾。
Proxy建好之後,就可以直接拿來呼叫,簡單吧!

        public static void main(String[] args) {
try{
WebService01Proxy proxy=new WebService01Proxy();
                        //取得server端資料
String en64=proxy.doZipQuery("select * from testTable ");

                        //解base64  
BASE64Decoder decoder = new BASE64Decoder();
byte[] b = decoder.decodeBuffer(en64);

                        //解壓縮
String rtn=StringUtil.uncompress(b);
System.out.println(rtn);
}catch(Exception e){
e.printStackTrace();
}finally{
}
}

/**
* 解壓縮
* @param str
* @return
* @throws IOException
*/
public static String uncompress(byte[] str) throws IOException {
if (str == null || str.length == 0) {
return null;
}
ByteArrayOutputStream out = new ByteArrayOutputStream();
ByteArrayInputStream in = new ByteArrayInputStream(str);
GZIPInputStream gunzip = new GZIPInputStream(in);
byte[] buffer = new byte[256];
int n;
while ((n = gunzip.read(buffer)) >= 0) {
out.write(buffer, 0, n);
}
return out.toString();
}