Android中使用gzip传递数据

来源:互联网 发布:软件测试靠谱吗 编辑:程序博客网 时间:2024/05/05 20:07
HTTP协议上的GZIP编码是一种用来改进WEB应用程序性能的技术。大流量的WEB站点常常使用GZIP压缩技术来减少文件大小,减少文件大小有两个明显的好处,一是可以减少存储空间,二是通过网络传输文件时,可以减少传输的时间。作者在写这篇博客时经过测试,4.4MB的文本数据经过Gzip传输到客户端之后变为392KB,压缩效率极高。
一.服务端
服务端有2种方式去压缩,一种可以自己压缩,但是更推荐第二种方式,用PrintWriter作为输出流,工具类代码如下
[java] view plaincopy
/** 
         * 判断浏览器是否支持 gzip 压缩 
         * @param req 
         * @return boolean 值 
         */  
        public static boolean isGzipSupport(HttpServletRequest req) {  
            String headEncoding = req.getHeader("accept-encoding");  
            if (headEncoding == null || (headEncoding.indexOf("gzip") == -1)) { // 客户端 不支持 gzip  
                return false;  
            } else { // 支持 gzip 压缩  
                return true;  
            }  
        }  
  
        /** 
         * 创建 以 gzip 格式 输出的 PrintWriter 对象,如果浏览器不支持 gzip 格式,则创建普通的 PrintWriter 对象, 
         * @param req 
         * @param resp 
         * @return 
         * @throws IOException 
         */  
        public static PrintWriter createGzipPw(HttpServletRequest req, HttpServletResponse resp) throws IOException {  
            PrintWriter pw = null;  
            if (isGzipSupport(req)) { // 支持 gzip 压缩  
                pw = new PrintWriter(new GZIPOutputStream(resp.getOutputStream()));  
                // 在 header 中设置返回类型为 gzip  
                resp.setHeader("content-encoding", "gzip");  
            } else { // // 客户端 不支持 gzip  
                pw = resp.getWriter();  
            }  
            return pw;  
        }  
      
servlet代码如下:
[java] view plaincopy
public void doPost(HttpServletRequest request, HttpServletResponse response)  
        throws ServletException, IOException {  
    response.setCharacterEncoding("utf-8");  
    response.setHeader("Content-Encoding", "gzip");  
    String ret = "{\"ContentLayer\":{\"title\":\"内容层\"},\"PageLink\":{\"title\":\"页面跳转\"},\"WebBrowser\":{\"title\":\"浏览器\"},"  
            + "\"InlinePage\":{\"title\":\"内嵌页面\"},\"VideoComp\":{\"title\":\"视频\"},"  
            + "\"PopButton\":{\"title\":\"内容开关\"},\"ZoomingPic\":{\"title\":\"缩放大图\"},"  
            + "\"Rotate360\":{\"title\":\"360度旋转\"}}";  
      
    PrintWriter pw = new PrintWriter(new GZIPOutputStream(response.getOutputStream()));  
    pw.write(ret);  
    pw.close();  
}  
  
public void doGet(HttpServletRequest request, HttpServletResponse response)  
        throws ServletException, IOException {  
    this.doPost(request, response);  
}  
在代理软件中跟踪到的数据如下:
[html] view plaincopy
??Vr??+Ií+?I?L-R2aV*é,éIU2R:r??YM??ju?óS}2ó2?e/m>üìì???@òá?INEù??¨ú???pà?w??g^Nf^*èTó?o?R???????[??à??c[á??8???????n?a?7@  
¢òós3óò2??U?toyè??g÷?T??$?¤? +r·??e??Zh¤??  


实际数据如下:
[html] view plaincopy
{"ContentLayer":{"title":"内容层"},"PageLink":{"title":"页面跳转"},"WebBrowser":{"title":"浏览器"},"InlinePage":{"title":"内嵌页面"},"VideoComp":{"title":"视频"},"PopButton":{"title":"内容开关"},"ZoomingPic":{"title":"缩放大图"},"Rotate360":{"title":"360度旋转"}}  


二.Android客户端
得到HttpClient代码:
[html] view plaincopy
private static DefaultHttpClient getHttpClient() {  
        DefaultHttpClient httpClient = new DefaultHttpClient();  
  
        // 设置 连接超时时间  
        httpClient.getParams().setParameter(  
                HttpConnectionParams.CONNECTION_TIMEOUT, TIMEOUT_CONNECTION);  
        // 设置 读数据超时时间  
        httpClient.getParams().setParameter(HttpConnectionParams.SO_TIMEOUT,  
                TIMEOUT_SOCKET);  
        // 设置 字符集  
        httpClient.getParams().setParameter("http.protocol.content-charset",  
                UTF_8);  
        return httpClient;  
    }  


得到HttpPost:
[java] view plaincopy
private static HttpPost getHttpPost(String url) {  
        HttpPost httpPost = new HttpPost(url);  
        // 设置 请求超时时间  
        httpPost.getParams().setParameter(HttpConnectionParams.SO_TIMEOUT,  
                TIMEOUT_SOCKET);  
        httpPost.setHeader("Connection", "Keep-Alive");  
        httpPost.addHeader("Accept-Encoding", "gzip");  
        return httpPost;  
    }  


访问网络代码:
[java] view plaincopy
public static InputStream http_post_return_byte(String url,  
            Map<String, String> params) throws AppException {  
        DefaultHttpClient httpclient = null;  
        HttpPost post = null;  
        HttpResponse response = null;  
        StringBuilder sb = null;  
        StringEntity stringEntity = null;  
        try {  
            httpclient = getHttpClient();  
            post = getHttpPost(url);  
            sb = new StringBuilder();  
            if (params != null && !params.isEmpty()) {  
                Logger.d("In http_post the url is get here");  
                for (Entry<String, String> entry : params.entrySet()) {  
                    sb.append(entry.getKey())  
                            .append("=")  
                            .append(URLEncoder.encode(entry.getValue(),  
                                    HTTP.UTF_8)).append("&");  
                }  
                sb.deleteCharAt(sb.lastIndexOf("&"));  
                Logger.d("In http_post the url is " + url + " and params is "  
                        + sb.toString());  
                stringEntity = new StringEntity(sb.toString());  
                stringEntity  
                        .setContentType("application/x-www-form-urlencoded");  
                post.setEntity(stringEntity);  
            }  
  
            response = httpclient.execute(post);  
            int statusCode = response.getStatusLine().getStatusCode();  
            Logger.d("statusCode is " + statusCode);  
            if (statusCode != HttpStatus.SC_OK) {  
                throw AppException.http(statusCode);  
            }  
  
            InputStream is = response.getEntity().getContent();  
  
            Header contentEncoding = response  
                    .getFirstHeader("Content-Encoding");  
            if (contentEncoding != null  
                    && contentEncoding.getValue().equalsIgnoreCase("gzip")) {  
                is = new GZIPInputStream(new BufferedInputStream(is));  
            }  
            return is;  
  
        } catch (ClientProtocolException e) {  
            e.printStackTrace();  
            throw AppException.http(e);  
        } catch (IOException e) {  
            e.printStackTrace();  
            throw AppException.network(e);  
        } finally {  
  
            /* 
             * if (!post.isAborted()) { 
             *  
             * post.abort(); } httpclient = null; 
             */  
  
        }  
  
    }  
原创粉丝点击