您的位置:首页 > 理论基础 > 计算机网络

Android开发--网络请求中GZip的使用

2012-09-11 14:20 507 查看
1、为什么要使用GZip?

HTTP协议上的GZIP编码是一种用来改进WEB应用程序性能的技术。大流量的WEB站点常常使用GZIP压缩技术来减少文件大小,减少文件大小有两个明显的好处,一是可以减少存储空间,二是通过网络传输文件时,可以减少传输的时间。

2、那如何在HTTP请求中使用GZip呢?

一般来说,在HTTP连接中,并不是所有的接收者都支持GZip格式的,所以根据HTTP协议,如果你可以处理GZip格式,并且希望服务器以GZip的格式来返回内容,需要在HTTP的请求的Header中声明"Accept-Encoding"为"gzip",如果服务器可以将内容压缩为GZip格式,那么服务器返回的Response的Header中将会设置"Content-Encoding" 属性的值是gzip,同时将返回的内容压缩为GZip格式。

3、在Android代码中如何实现GZip呢?

首先要在Http请求中加入支持GZip格式的声明,不同HTTP连接对象的设置方式也不相同,我们以HttpGet来举例:

httpRequest = newHttpGet(url);

httpRequest.addHeader("Accept-Encoding", "gzip");

接收到服务器的返回时,要根据Response的Header中"Content-Encoding" 的值来绝定是否需要解压GZip内容,Android的SDK中内置了GZIPInputStream可以帮助我们解压GZip流得到一个正常的输入流。

HttpEntity httpEntity = httpResponse.getEntity();

InputStream is= httpEntity.getContent();

if (httpEntity.getContentEncoding().getValue().contains("gzip")) {

is= new GZIPInputStream(is);

}

OK,这样就可以实现了,简单吧,大家觉得有什么不对劲了吗?这么好用的一项功能难道这么简单就可以实现?没错,如果不是在天朝写成如此就已经可以了,但是在天朝,我们当然不会这么省心。

在我国移动运营商“创新性”地弄了一种名叫“WAP”的网络,在常规的状况下WAP网络下只能访问WAP的内网,这就是使用WAP接入点时所有国外的应用都无法使用的原因。WAP网络为我们带来了两个难题:1是如何在WAP网络中访问外网,2是WAP网络的路由器会对流经的数据进行处理,很奇怪对不对,就好像是我们往来的信件会被人偷看,不仅仅是偷看,它还会做修改呢,很多的HTTP请求中的Header会被过滤掉,gzip的头也在其中,路由器过滤掉gzip标示的同时会把内容解压,这样我们的gzip就不起作用了。

怎样可以绕过那些路由器的过滤呢?比较简单的一个方法是服务器的返回不遵守HTTP协议,内容使用GZip压缩,但是不返回Content-Encoding=gzip,这样路由器就没有办法了。

如果这样我们的程序也要进行一定的修改,因为不能判断Content-Encoding来解压GZip了。我们可以输入流读取前两个字节,如果是0x8B1F,就认为是GZip格式。但是InputStream读过一次流就无法使用了,虽然它有reset方法,但是不知为何不起作用。经过试验我们选择了使用BufferedInputStream来中转,因为它可以通过reset来重新定位到流的开头。

BufferedInputStream bis = new BufferedInputStream(is);

bis.mark(2);

// 取前两个字节

byte[] header = new byte[2];

int result = bis.read(header);

// reset输入流到开始位置

bis.reset();

// 判断是否是GZIP格式

if(result!=-1 && getShort(header, 0)==0x8b1f) {

is= new GZIPInputStream(bis);

} else {

// 取前两个字节

is= bis;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: