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

一.服务端

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

[java]  view plain copy

 
  1. /**
  2. * 判断浏览器是否支持 gzip 压缩
  3. * @param req
  4. * @return boolean 值
  5. */
  6. public static boolean isGzipSupport(HttpServletRequest req) {
  7. String headEncoding = req.getHeader("accept-encoding");
  8. if (headEncoding == null || (headEncoding.indexOf("gzip") == -1)) { // 客户端 不支持 gzip
  9. return false;
  10. } else { // 支持 gzip 压缩
  11. return true;
  12. }
  13. }
  14. /**
  15. * 创建 以 gzip 格式 输出的 PrintWriter 对象,如果浏览器不支持 gzip 格式,则创建普通的 PrintWriter 对象,
  16. * @param req
  17. * @param resp
  18. * @return
  19. * @throws IOException
  20. */
  21. public static PrintWriter createGzipPw(HttpServletRequest req, HttpServletResponse resp) throws IOException {
  22. PrintWriter pw = null;
  23. if (isGzipSupport(req)) { // 支持 gzip 压缩
  24. pw = new PrintWriter(new GZIPOutputStream(resp.getOutputStream()));
  25. // 在 header 中设置返回类型为 gzip
  26. resp.setHeader("content-encoding", "gzip");
  27. } else { // // 客户端 不支持 gzip
  28. pw = resp.getWriter();
  29. }
  30. return pw;
  31. }

servlet代码如下:

[java] 
view plain
copy

 

  1. public void 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\":\"内容层\"},\"PageLink\":{\"title\":\"页面跳转\"},\"WebBrowser\":{\"title\":\"浏览器\"},"
  6. + "\"InlinePage\":{\"title\":\"内嵌页面\"},\"VideoComp\":{\"title\":\"视频\"},"
  7. + "\"PopButton\":{\"title\":\"内容开关\"},\"ZoomingPic\":{\"title\":\"缩放大图\"},"
  8. + "\"Rotate360\":{\"title\":\"360度旋转\"}}";
  9. PrintWriter pw = new PrintWriter(new GZIPOutputStream(response.getOutputStream()));
  10. pw.write(ret);
  11. pw.close();
  12. }
  13. public void doGet(HttpServletRequest request, HttpServletResponse response)
  14. throws ServletException, IOException {
  15. this.doPost(request, response);
  16. }

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

[html] 
view plain
copy

 

  1. ‹«VrÎÏ+IÍ+ñI¬L-R²ªV*É,ÉIU²R:rëÄÝM•ju”ÓS}2ó²‘e/m>üì̏ë«@òá©INEùåŨúŸ¬?pàØw¼g^Nf^*ÈTóo™R–™’šïœŸ[€¬àÔåc[ÁÖç8•–”äç¡»nÿª7@
  2. ¢òós3óÒ2“‘Uœþºýè–Ïg÷€Tå—$–¤› +r·¸ðä‡Zh¤†ˆ

实际数据如下:

[html] 
view plain
copy

 

  1. {"ContentLayer":{"title":"内容层"},"PageLink":{"title":"页面跳转"},"WebBrowser":{"title":"浏览器"},"InlinePage":{"title":"内嵌页面"},"VideoComp":{"title":"视频"},"PopButton":{"title":"内容开关"},"ZoomingPic":{"title":"缩放大图"},"Rotate360":{"title":"360度旋转"}}

二.Android客户端

得到HttpClient代码:

[html] 
view plain
copy

 

  1. private static DefaultHttpClient getHttpClient() {
  2. DefaultHttpClient httpClient = new DefaultHttpClient();
  3. // 设置 连接超时时间
  4. httpClient.getParams().setParameter(
  5. HttpConnectionParams.CONNECTION_TIMEOUT, TIMEOUT_CONNECTION);
  6. // 设置 读数据超时时间
  7. httpClient.getParams().setParameter(HttpConnectionParams.SO_TIMEOUT,
  8. TIMEOUT_SOCKET);
  9. // 设置 字符集
  10. httpClient.getParams().setParameter("http.protocol.content-charset",
  11. UTF_8);
  12. return httpClient;
  13. }

得到HttpPost:

[java] 
view plain
copy

 

  1. private static HttpPost getHttpPost(String url) {
  2. HttpPost httpPost = new HttpPost(url);
  3. // 设置 请求超时时间
  4. httpPost.getParams().setParameter(HttpConnectionParams.SO_TIMEOUT,
  5. TIMEOUT_SOCKET);
  6. httpPost.setHeader("Connection", "Keep-Alive");
  7. httpPost.addHeader("Accept-Encoding", "gzip");
  8. return httpPost;
  9. }

访问网络代码:

[java] 
view plain
copy

 

  1. public static 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.entrySet()) {
  15. sb.append(entry.getKey())
  16. .append("=")
  17. .append(URLEncoder.encode(entry.getValue(),
  18. HTTP.UTF_8)).append("&");
  19. }
  20. sb.deleteCharAt(sb.lastIndexOf("&"));
  21. Logger.d("In http_post the url is " + url + " and params is "
  22. + sb.toString());
  23. stringEntity = new StringEntity(sb.toString());
  24. stringEntity
  25. .setContentType("application/x-www-form-urlencoded");
  26. post.setEntity(stringEntity);
  27. }
  28. response = httpclient.execute(post);
  29. int statusCode = response.getStatusLine().getStatusCode();
  30. Logger.d("statusCode is " + statusCode);
  31. if (statusCode != HttpStatus.SC_OK) {
  32. throw AppException.http(statusCode);
  33. }
  34. InputStream is = response.getEntity().getContent();
  35. Header contentEncoding = response
  36. .getFirstHeader("Content-Encoding");
  37. if (contentEncoding != null
  38. && contentEncoding.getValue().equalsIgnoreCase("gzip")) {
  39. is = new GZIPInputStream(new BufferedInputStream(is));
  40. }
  41. return is;
  42. } catch (ClientProtocolException e) {
  43. e.printStackTrace();
  44. throw AppException.http(e);
  45. } catch (IOException e) {
  46. e.printStackTrace();
  47. throw AppException.network(e);
  48. } finally {
  49. /*
  50. * if (!post.isAborted()) {
  51. *
  52. * post.abort(); } httpclient = null;
  53. */
  54. }
  55. }

Android中使用gzip传递数据的更多相关文章

  1. Xamarin Android 中Acitvity如何传递数据

    在xamarin android的开发中,activity传递数据非常常见,下面我也来记一下在android中activity之间传递数据的几种方式, Xamarin Android中Activity ...

  2. android中的事件传递和处理机制

    一直以来,都被android中的事件传递和处理机制深深的困扰!今天特意来好好的探讨一下.现在的感觉是,只要你理解到位,其实事件的 传递和处理机制并没有想象中的那么难.总之,不要自己打击自己,要相信自己 ...

  3. Android中突发情况Activity数据的保存和恢复

    Android中突发情况Activity数据的保存和恢复 写在前面:在我们的APP使用的过程中,总有可能出现各种手滑.被压在后台.甚至突然被杀死的情况.所以对APP中一些临时数据或关键持久型数据,就需 ...

  4. Android中解析XML格式数据的方法

    XML介绍:Extensible Markup Language,即可扩展标记语言 一.概述 Android中解析XML格式数据大致有三种方法: SAX DOM PULL 二.详解 2.1 SAX S ...

  5. Android 开发中使用Intent传递数据的方法

    Activity之间通过Intent传递值,支持基本数据类型和String对象及 它们的数组对象byte.byte[].char.char[].boolean.boolean[].short.shor ...

  6. android中通过intent传递复杂数据

    android中在各个service或者acitivity之间可以通过Intent来传递一些数据,intent原生直接提供了一些简单数据类型的数据的传递,使用起来也很方便,比如int boolean ...

  7. Android中Activity之间的数据传递

    在开发中,我们经常涌用到Activity,那么既然用到了Activity,就一定免不了在两个或者多个Activity之间传递数据.这里我们先说一说原理,然后在看看代码和例子. 情况A:我们需要从Act ...

  8. Android程序中Acticity间传递数据

    在Android开发过程中,在不同的Acitivity之间传递数据的情况是非常常见的.我花费了一点时间来总结Acitivity之间的数据传递,记录下来. 1.简单传递键值对 这种传递方式非常简单,只需 ...

  9. Android 使用剪切板传递数据

    使用剪切板传递数据,可以传递简单的数据,也可以传递可序列化的对象. 首先来个简单点吧. 首先在,mainActivity.xml文件中加入一个button按钮 private Button butto ...

随机推荐

  1. 51nod1627 瞬间移动

    打表可以看出来是组合数...妈呀为什么弄成n+m-4,n-1,m-3就错啊... //打表可以看出来是组合数...妈呀为什么弄成n+m-4,n-1,m-3就错啊... #include<cstd ...

  2. cocos2d-x使用python脚本创建项目的简单方法

    本文有CC原创,转载请注明地址:http://blog.csdn.net/oktears/article/details/13297003 在cocos2d-x2.1.4以上的版本中,取消了使用vs模 ...

  3. scala学习笔记(4):占位符

    scala 中占位符的用法 1.作为“通配符”,类似Java中的*.如import scala.math._ 2.:_*作为一个整体,告诉编译器你希望将某个参数当作参数序列处理!例如val s = s ...

  4. 【解题报告】[动态规划] RQNOJ - PID38 / 串的记数

    原题地址:http://www.rqnoj.cn/problem/38 解题思路: 状态表示:dp[i][j][k]表示i个A,j个B,k个C组成的满足条件的字符串的个数 初始状态:dp[0][0][ ...

  5. jquery事件学习笔记(转载)

    一.页面载入1.ready(fn)当DOM载入就绪可以查询及操纵时绑定一个要执行的函数.这是事件模块中最重要的一个函数,因为它可以极大地提高web应用程序的响应速度. 简单地说,这个方法纯粹是对向wi ...

  6. NodeJS学习笔记之MongoDB模块

    其中还有,nodejs远程连接mysql数据库 一,开篇分析 这篇属于扩展知识篇,因为在下面的文章中会用到数据库操作,所以今天就来说说它(Mongodb模块). (1),简介 MongoDB是一个基于 ...

  7. UIImageView 点击放大缩小

    static CGRect oldframe; -(void)showImage:(UIImageView *)avatarImageView{ UIImage *image=avatarImageV ...

  8. 单机版搭建Hadoop环境图文教程详解

    安装过程: 一.安装Linux操作系统二.在Ubuntu下创建hadoop用户组和用户三.在Ubuntu下安装JDK四.修改机器名五.安装ssh服务六.建立ssh无密码登录本机七.安装hadoop八. ...

  9. JDBC项目实践

    这几天学习了JDBC的接口,从简单的连接,到不断地对JDBC的代码进行优化,最后到实体类,DAO类的设计,现在对这几天所学做一个总结: 首先是软件的系统组成: 数据库中有很多的表:Customer,D ...

  10. iOS学习笔记之回调(二)

    写在前面 上一篇学习笔记中简单介绍了通过目标-动作对实现回调操作:创建两个对象timer和logger,将logger设置为timer的目标,timer定时调用logger的sayOuch函数.在这个 ...