Android中使用gzip传递数据
HTTP协议上的GZIP编码是一种用来改进WEB应用程序性能的技术。大流量的WEB站点常常使用GZIP压缩技术来减少文件大小,减少文件大小有两个明显的好处,一是可以减少存储空间,二是通过网络传输文件时,可以减少传输的时间。作者在写这篇博客时经过测试,4.4MB的文本数据经过Gzip传输到客户端之后变为392KB,压缩效率极高。
一.服务端
服务端有2种方式去压缩,一种可以自己压缩,但是更推荐第二种方式,用PrintWriter作为输出流,工具类代码如下
- /**
- * 判断浏览器是否支持 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代码如下:
- 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);
- }
在代理软件中跟踪到的数据如下:
- «VrÎÏ+IÍ+ñI¬L-R²ªV*É,ÉIU²R:rëÄÝMjuÓS}2ó²e/m>üìÌë«@òá©INEùåŨú¬?pàØw¼g^Nf^*ÈTóoRï[¬àÔåc[ÁÖç8äç¡»nÿª7@
- ¢òós3óÒ2UþºýèÏg÷Tå$¤ +r·¸ðäZh¤
实际数据如下:
- {"ContentLayer":{"title":"内容层"},"PageLink":{"title":"页面跳转"},"WebBrowser":{"title":"浏览器"},"InlinePage":{"title":"内嵌页面"},"VideoComp":{"title":"视频"},"PopButton":{"title":"内容开关"},"ZoomingPic":{"title":"缩放大图"},"Rotate360":{"title":"360度旋转"}}
二.Android客户端
得到HttpClient代码:
- 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:
- 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;
- }
访问网络代码:
- 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;
- */
- }
- }
Android中使用gzip传递数据的更多相关文章
- Xamarin Android 中Acitvity如何传递数据
在xamarin android的开发中,activity传递数据非常常见,下面我也来记一下在android中activity之间传递数据的几种方式, Xamarin Android中Activity ...
- android中的事件传递和处理机制
一直以来,都被android中的事件传递和处理机制深深的困扰!今天特意来好好的探讨一下.现在的感觉是,只要你理解到位,其实事件的 传递和处理机制并没有想象中的那么难.总之,不要自己打击自己,要相信自己 ...
- Android中突发情况Activity数据的保存和恢复
Android中突发情况Activity数据的保存和恢复 写在前面:在我们的APP使用的过程中,总有可能出现各种手滑.被压在后台.甚至突然被杀死的情况.所以对APP中一些临时数据或关键持久型数据,就需 ...
- Android中解析XML格式数据的方法
XML介绍:Extensible Markup Language,即可扩展标记语言 一.概述 Android中解析XML格式数据大致有三种方法: SAX DOM PULL 二.详解 2.1 SAX S ...
- Android 开发中使用Intent传递数据的方法
Activity之间通过Intent传递值,支持基本数据类型和String对象及 它们的数组对象byte.byte[].char.char[].boolean.boolean[].short.shor ...
- android中通过intent传递复杂数据
android中在各个service或者acitivity之间可以通过Intent来传递一些数据,intent原生直接提供了一些简单数据类型的数据的传递,使用起来也很方便,比如int boolean ...
- Android中Activity之间的数据传递
在开发中,我们经常涌用到Activity,那么既然用到了Activity,就一定免不了在两个或者多个Activity之间传递数据.这里我们先说一说原理,然后在看看代码和例子. 情况A:我们需要从Act ...
- Android程序中Acticity间传递数据
在Android开发过程中,在不同的Acitivity之间传递数据的情况是非常常见的.我花费了一点时间来总结Acitivity之间的数据传递,记录下来. 1.简单传递键值对 这种传递方式非常简单,只需 ...
- Android 使用剪切板传递数据
使用剪切板传递数据,可以传递简单的数据,也可以传递可序列化的对象. 首先来个简单点吧. 首先在,mainActivity.xml文件中加入一个button按钮 private Button butto ...
随机推荐
- LA 4255 (拓扑排序 并查集) Guess
设这个序列的前缀和为Si(0 <= i <= n),S0 = 0 每一个符号对应两个前缀和的大小关系,然后根据这个关系拓扑排序一下. 还要注意一下前缀和相等的情况,所以用一个并查集来查询. ...
- HTML元素margin、padding的默认值
HTML元素margin.padding的默认值 element margin(单位像素) padding html 0 0 body 8 0 div 0 0 h1 21 0 h2 19 0 19 0 ...
- python练习程序(c100经典例10)
题目: 打印楼梯,同时在楼梯上方打印两个笑脸. print '..' for i in range(1,9): print '**' for j in range(1,i+1): print ' ',
- 基于jquery框架的ajax搜索显示
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <hea ...
- 通过 XtraBackup 实现不停机不锁表搭建主从同步
简介 Xtrabackup是由 Percona 开发的一个开源软件,可实现对 InnoDB 的数据备份,支持在线热备份(备份时不影响数据读写).备份时,Xtrabackup 会将 Master 的 b ...
- 查看Linux下端口占用情况的命令
在使用Linux系统的过程中,有时候会遇到端口被占用而导致服务无法启动的情况.比如HTTP使用80端口,但当启动Apache时,却发现此端口正在使用. 这种情况大多数是由于软件冲突.或者默认端口设置不 ...
- Java 中无参带返回值方法的使用
如果方法不包含参数,但有返回值,我们称为无参带返回值的方法. 例如:下面的代码,定义了一个方法名为 calSum ,无参数,但返回值为 int 类型的方法,执行的操作为计算两数之和,并返回结果 在 c ...
- IT技术人士 不能一辈子靠技术生存
我现在是自己做,但我此前有多年在从事软件开发工作,当回过头来想一想自己,觉得特别想对那些初学JAVA/DOT.NET技术的朋友说点心里话,希望你们能从我们的体会中,多少受点启发(也许我说的不好,你不赞 ...
- pageX,clientX,offsetX,layerX的区别
pageX,clientX,offsetX,layerX的区别 在各个浏览器的JS中,有很多个让你十分囧的属性,由于各大厂商对标准的解释和执行不一样,导致十分混乱,也让我们这些前端攻城狮十分无语和纠结 ...
- Redis 对String数据类型的操作
Redis的 Strings 数据结构是简单的key-value类型,value其实不仅是String,也可以是数字.使用Strings类型,你可以完全实现目前 Memcached 的功能,并且效率更 ...