Android中使用gzip传递数据

来源:互联网 发布:mac 重新安装程序 编辑:程序博客网 时间:2024/05/19 05:38
摘要:Android中使用gzip传递数据,HTTP协议上的GZIP编码是一种用来改进WEB应用程序性能的技术。

HTTP协议上的GZIP编码是一种用来改进WEB应用程序性能的技术。大流量的WEB站点常常使用GZIP压缩技术来减少文件大小,减少文件大小有两个明显的好处,一是可以减少存储空间,二是通过网络传输文件时,可以减少传输的时间。作者在写这篇博客时经过测试,4.4MB的文本数据经过Gzip传输到客户端之后变为392KB,压缩效率极高。

一.服务端

服务端有2种方式去压缩,一种可以自己压缩,但是更推荐第二种方式,用PrintWriter作为输出流,工具类代码如下:

[java]view plaincopy
  1.              /**

  2. * 判断浏览器是否支持 gzip 压缩

  3. * @param req

  4. * @return boolean 值

  5. */  

  6. publicstaticboolean isGzipSupport(HttpServletRequest req) {  

  7.    String headEncoding = req.getHeader("accept-encoding");  

  8.    if (headEncoding == null || (headEncoding.indexOf("gzip")

  9. == -1)) { // 客户端 不支持 gzip  

  10.        returnfalse;  

  11.    } else { // 支持 gzip 压缩  

  12.        returntrue;  

  13.    }  

  14. }  

  15.  

  16. /**

  17. * 创建 以 gzip 格式 输出的 PrintWriter 对象,如果浏览器不支持

  18. gzip 格式,则创建普通的 PrintWriter 对象,

  19. * @param req

  20. * @param resp

  21. * @return

  22. * @throws IOException

  23. */  

  24. publicstatic PrintWriter createGzipPw(HttpServletRequest req,

  25. HttpServletResponse resp) throws IOException {  

  26.    PrintWriter pw = null;  

  27.    if (isGzipSupport(req)) { // 支持 gzip 压缩  

  28.        pw = new PrintWriter(new GZIPOutputStream

  29. (resp.getOutputStream()));  

  30.        // 在 header 中设置返回类型为 gzip  

  31.        resp.setHeader("content-encoding","gzip");  

  32.    } else { // // 客户端 不支持 gzip  

  33.        pw = resp.getWriter();  

  34.    }  

  35.    return pw;  

  36. }  

servlet代码如下:

[java]view plaincopy
  1. publicvoid doPost(HttpServletRequest request, HttpServletResponse response)  

  2.        throws ServletException, IOException {  

  3.    response.setCharacterEncoding("utf-8");  

  4.    response.setHeader("Content-Encoding","gzip");  

  5.    String ret = "{\"ContentLayer\":{\"title\":\"内容层\"},

  6. \"PageLink\":{\"title\":\"页面跳转\"},\"WebBrowser\":{\"title\":\

  7. "浏览器\"},"  

  8.            + "\"InlinePage\":{\"title\":\"内嵌页面\"},\"VideoComp

  9. \":{\"title\":\"视频\"},"  

  10.            + "\"PopButton\":{\"title\":\"内容开关\"},\"ZoomingPic

  11. \":{\"title\":\"缩放大图\"},"  

  12.            + "\"Rotate360\":{\"title\":\"360度旋转\"}}";  

  13.      

  14.    PrintWriter pw = new PrintWriter(new GZIPOutputStream

  15. (response.getOutputStream()));  

  16.    pw.write(ret);  

  17.    pw.close();  

  18. }  

  19.  

  20. publicvoid doGet(HttpServletRequest request, HttpServletResponse

  21. response)  

  22.        throws ServletException, IOException {  

  23.    this.doPost(request, response);  

  24. }  

在代理软件中跟踪到的数据如下:

[plain]view plaincopy
  1. ‹«VrÎÏ+IÍ+ñI¬L-R²ªV*É,ÉIU²R:rëÄÝM•ju”ÓS}2ó²‘e/m>üì̏ë«@òá©INEùåŨúŸ¬?

  2. pàØw¼g^Nf^*ÈTóo™R–™’šïœŸ[€¬àÔåc[ÁÖç8•–”äç¡»nÿª7@  

  3. ¢òós3óÒ2“‘Uœþºýè–Ïg÷€Tå—$–¤› +r·¸ðä‡Zh¤†ˆ  

实际数据如下:

[java]view plaincopy
  1. {"ContentLayer":{"title":"内容层"},"PageLink":{"title":"页面跳转"},

  2. "WebBrowser":{"title":"浏览器"},"InlinePage":{"title":"内嵌页面"},

  3. "VideoComp":{"title":"视频"},"PopButton":{"title":"内容开关"},

  4. "ZoomingPic":{"title":"缩放大图"},"Rotate360":{"title":"360度旋转"

  5. }}  

二.Android客户端

得到HttpClient代码:

[java]view plaincopy
  1. privatestatic DefaultHttpClient getHttpClient() {  

  2.        DefaultHttpClient httpClient = new DefaultHttpClient();  

  3.  

  4.        // 设置 连接超时时间  

  5.        httpClient.getParams().setParameter(  

  6.                HttpConnectionParams.CONNECTION_TIMEOUT, TIMEOUT_

  7. CONNECTION);  

  8.        // 设置 读数据超时时间  

  9.        httpClient.getParams().setParameter(HttpConnectionParams.

  10. SO_TIMEOUT,  

  11.                TIMEOUT_SOCKET);  

  12.        // 设置 字符集  

  13.        httpClient.getParams().setParameter("http.protocol.

  14. content-charset",  

  15.                UTF_8);  

  16.        return httpClient;  

  17.    }  

得到HttpPost:

[java]view plaincopy
  1. privatestatic HttpPost getHttpPost(String url) {  

  2.        HttpPost httpPost = new HttpPost(url);  

  3.        // 设置 请求超时时间  

  4.        httpPost.getParams().setParameter(HttpConnectionParams.SO_

  5. TIMEOUT,  

  6.                TIMEOUT_SOCKET);  

  7.        httpPost.setHeader("Connection","Keep-Alive");  

  8.        httpPost.addHeader("Accept-Encoding","gzip");  

  9.        return httpPost;  

  10.    }  


访问网络代码:

[java]view plaincopy
  1. publicstatic InputStream http_post_return_byte(String url,  

  2.            Map<String, String> params) throws AppException {  

  3.        DefaultHttpClient httpclient = null;  

  4.        HttpPost post = null;  

  5.        HttpResponse response = null;  

  6.        StringBuilder sb = null;  

  7.        StringEntity stringEntity = null;  

  8.        try {  

  9.            httpclient = getHttpClient();  

  10.            post = getHttpPost(url);  

  11.            sb = new StringBuilder();  

  12.            if (params != null && !params.isEmpty()) {  

  13.                Logger.d("In http_post the url is get here");  

  14.                for (Entry<String, String> entry : params.

  15. entrySet()) {  

  16.                    sb.append(entry.getKey())  

  17.                            .append("=")  

  18.                            .append(URLEncoder.encode(entry.

  19. getValue(),  

  20.                                    HTTP.UTF_8)).append("&");  

  21.                }  

  22.                sb.deleteCharAt(sb.lastIndexOf("&"));  

  23.                Logger.d("In http_post the url is " + url +" and

  24. params is "  

  25.                        + sb.toString());  

  26.                stringEntity = new StringEntity(sb.toString());  

  27.                stringEntity  

  28.                        .setContentType

  29. ("application/x-www-form-urlencoded");  

  30.                post.setEntity(stringEntity);  

  31.            }  

  32.  

  33.            response = httpclient.execute(post);  

  34.            int statusCode = response.getStatusLine().

  35. getStatusCode();  

  36.            Logger.d("statusCode is " + statusCode);  

  37.            if (statusCode != HttpStatus.SC_OK) {  

  38.                throw AppException.http(statusCode);  

  39.            }  

  40.  

  41.            InputStream is = response.getEntity().getContent();  

  42.  

  43.            Header contentEncoding = response  

  44.                    .getFirstHeader("Content-Encoding");  

  45.            if (contentEncoding != null  

  46.                    && contentEncoding.getValue().

  47. equalsIgnoreCase("gzip")) {  

  48.                is = new GZIPInputStream(new BufferedInputStream

  49. (is));  

  50.            }  

  51.            return is;  

  52.  

  53.        } catch (ClientProtocolException e) {  

  54.            e.printStackTrace();  

  55.            throw AppException.http(e);  

  56.        } catch (IOException e) {  

  57.            e.printStackTrace();  

  58.            throw AppException.network(e);  

  59.        } finally {  

  60.  

  61.            /*

  62.             * if (!post.isAborted()) {

  63.             *

  64.             * post.abort(); } httpclient = null;

  65.             */  

  66.  

  67.        }  

  68.  

  69.    }  

原创粉丝点击