关于ETag和Gzip的基本认知和使用
来源:互联网 发布:大数据洞察有哪些特色 编辑:程序博客网 时间:2024/05/20 12:46
题引:为了提升用户体验,同时减轻服务器压力和降低网络带宽,技术总监和技术经理决定对APP做缓存和压缩处理,包括图片的三级缓存(这里不讨论)和网络请求的数据缓存和压缩
- ETag的基本认识
- ETag的基本使用
- Gzip的基本认识
- Gzip的基本使用
- 判读服务器是否返回压缩数据的方式
- 服务端Nginx配置ETag和Gzip冲突的解决方案
- Refer
一、ETag的基本认识
以下四篇文章讲解的都是ETag的基本知识:
- 客户端HTTP协议缓存的研究
- If-Modified-Since & If-None-Match
- REST笔记(五):你应该知道的HTTP头——ETag
- http协议-缓存统制:etag If-None-Match / Last-Modified If-Modified-Since
二、ETag的基本使用
ETag的使用就Android客户端来说,大概有两个步骤:
- Header添加If-None-Match/ETag信息
- 执行请求返回响应体后做相应的缓存处理
三、Gzip的基本认识
HTTP协议上的GZIP编码是一种用来改进WEB应用程序性能的技术。大流量的WEB站点常常使用GZIP压缩技术来减少文件大小,减少文件大小有两个明显的好处,一是可以减少存储空间,二是通过网络传输文件时,可以减少传输的时间。
四、Gzip的基本使用
Gzip的基本使用就Android客户端来说,大概有两个步骤:
- Header添加Accept-Encoding属性值为gzip
- 执行请求返回响应体后做相应的解压处理
附样板代码如下:
1、获取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; }
2、获取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; }
3、访问网络及解压
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; */ } }
五、判断网络返回的数据是否经过压缩
- 从Http 技术细节上讲,request头中如果有 “Accept-Encoding”,”gzip”,response中就有返回头”Content-Encoding”:”gzip”,因此可以通过判读响应体是否有Content-Encoding属性,并且其值为gzip。
- gzip流前两个字节是0x1f8b,因此可通过判断输入流的前两个字节是否为0x1f8b。
附具体代码如下:
private String getJsonStringFromGZIP(HttpResponse response) { String jsonString = null; try { InputStream is = response.getEntity().getContent(); BufferedInputStream bis = new BufferedInputStream(is); bis.mark(2); // 取前两个字节 byte[] header = new byte[2]; int result = bis.read(header); // reset输入流到开始位置 bis.reset(); // 判断是否是GZIP格式 int headerData = getShort(header); // Gzip 流 的前两个字节是 0x1f8b if (result != -1 && headerData == 0x1f8b) { LogUtil.d("HttpTask", " use GZIPInputStream "); is = new GZIPInputStream(bis); } else { LogUtil.d("HttpTask", " not use GZIPInputStream"); is = bis; } InputStreamReader reader = new InputStreamReader(is, "utf-8"); char[] data = new char[100]; int readSize; StringBuffer sb = new StringBuffer(); while ((readSize = reader.read(data)) > 0) { sb.append(data, 0, readSize); } jsonString = sb.toString(); bis.close(); reader.close(); } catch (Exception e) { LogUtil.e("HttpTask", e.toString(),e); } LogUtil.d("HttpTask", "getJsonStringFromGZIP net output : " + jsonString ); return jsonString; } private int getShort(byte[] data) { return (int)((data[0]<<8) | data[1]&0xFF); }
六、服务端Nginx配置ETag和Gzip冲突的解决方案
以下三篇文章都涉及到ETag和Gzip冲突的解决方案:
- nginx开启gzip模块后ETAG丢失
- nginx - missing etag when gzip is used
- Nginx如何开启ETag,提高访问速度
七、Refer
- Android中使用gzip传递数据
- Android开发中网络请求的压缩 ── GZip的使用
0 0
- 关于ETag和Gzip的基本认知和使用
- Fragment的基础认知和基本使用
- 浅谈block的基本使用和基本认知.
- 关于http的Last-Modified和ETag
- 关于http的Last-Modified和ETag
- 了解和使用keystone(一)keystone的基本认知
- 关于何时使用实体标签ETag和最后修改时间(Last-modified)的规则
- gzip 和 gunzip 的使用
- 关于cmwap和gzip
- 关于大数据和NoSQL和的一些片面认知
- (一)对 java的发展史和体系结构基本认知。
- IE6上Gzip+Etag问题的解决方案
- IE6上Gzip+Etag问题的解决方案
- tar和gzip命令的使用
- HTTP的Last-Modified和Etag
- 【IT情感】关于专业、理想和工作的认知
- 黑马程序员关于进程和线程的认知
- 关于认知计算的一点浏览和摘录
- Android开发中"逃避式"防止大多数Crash的策略
- Linux环境下安装ssh2模块
- 微信jssdk,实现多图上传的一点心得
- 【搜索】洛谷 P1461 海明码 Hamming Codes
- 何洋开讲丨“云”将如何在中国制造2025中起到颠覆作用?
- 关于ETag和Gzip的基本认知和使用
- 字符设备
- 碰撞检测经典解决方案
- centos目录结构详细版
- STL的容器、算法与迭代器
- mybatis,hibernate,jdbcTemplate怎么返回map以及一些操作技巧
- js修改页面title
- 基于Python多线程的TCP客户端/服务端应用示例
- 手动解析json