httpclient中GzipDecompressingEntity 类的使用

在用httpclient做网页提取的过程中,通过抓包工具发现了 头部中会有 Accept-Encoding: gzip, deflate字段,本文不介绍该字段具体是干什么的,只是告诉你在请求的时候,如果头部有了该字段,则服务器会将内容reponse的内容进行压缩用gzip或者deflate算法,然后reponse给用户。目前我看到的仅仅有gzip算法被用到,然后返回给用户的数据也是压缩后的数据,这样往往可以减轻服务器的负担,同时也减少了网络传输。以下用浏览器在访问百度主页是抓包的例子:

GET / HTTP/1.1

Accept:image/gif,image/jpeg,image/pjpeg,image/pjpeg,application/x-shockwave-flash,application/vnd.ms-excel,application/vnd.ms-powerpoint,application/msword,application/xaml+xml,application/x-ms-xbap,application/x-ms-application,*/*

Accept-Language:zh-cn

User-Agent:Mozilla/4.0(compatible;MSIE8.0;WindowsNT5.1;Trident/4.0;chromeframe/16.0.912.63;QQDownload708;.NETCLR2.0.50727;.NET4.0C;.NET4.0E)

Accept-Encoding:gzip,deflate

Host:www.baidu.com

Connection: Keep-Alive

在头部中有Accept-Encoding: gzip, deflate字段,则服务器会将响应进行压缩,返回。我们在用浏览器查看时,并没有觉察到这一切的发生,是因为,浏览器已经帮我们进行了解压缩,这样百度主页的内容得以正常显示。

现在的问题是如果我编程时,如果用到了Accept-Encoding: gzip, deflate字段呢?当然如果,你去掉了该字段,服务器返回给你的当然是没有压缩过的内容,所见即所得。可是如果有了该字段,你又不处理,那么就会遇到乱码现象(这是肯定的,因为只是压缩过的数据)。下边我会利用httpclient工具对加入了Accept-Encoding: gzip, deflate 的内容进行处理,使得内容可以正常处理。

主要有两个关于解压缩的类:

DeflateDecompressingEntity GzipDecompressingEntity 

我们只用了第二个GzipDecompressingEntity  ,使用它非常简单,只需要

<strong><code><strong>GzipDecompressingEntity <code><strong><code><strong><code><strong><code><strong>gzipDecompressingEntity</strong>=new GzipDecompressingEntity(HttpEntity entity)即可。

这里的参数 entity是原来压缩过的entity.下边是一个完整的例子:

String url="http://www.baidu.com";
		Map<String,String> headers=new HashMap<String,String>();
		headers.put("Accept", "*/*");  
		headers.put("Accept-Language", "zh-cn");  
		headers.put("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; chromeframe/16.0.912.63; QQDownload 708; .NET CLR 2.0.50727; .NET4.0C; .NET4.0E)");  
		headers.put("Accept-Encoding", "gzip, deflate");  
		headers.put("Host", "www.baidu.com");  
		headers.put("Connection", "Keep-Alive");  
		HttpResponse response=HttpUtils.doGet(url, headers);
		HttpEntity entity1=response.getEntity(); //压缩过的entity
		long len=entity1.getContentLength();//压缩过的长度
		System.out.println(entity1.getContentType());//类型
		System.out.println(entity1.getContentEncoding().getValue());//压缩类型
		System.out.println("gzip:压缩前的内容长度"+len);
		GzipDecompressingEntity entity=new GzipDecompressingEntity(entity1);
		InputStream in=entity.getContent();
		String str=Utils.getStringFromStream(in);
		System.out.println("实际内容长度为:"+str.getBytes().length);

 程序运行结果为:

Content-Type: text/html;charset=gb2312

gzip

gzip:压缩前的内容长度3400

实际内容长度为:8039

由此可见,压缩前与解压缩后比,内容长度只有源内容大小的不到一半,采用压缩还是很能够节约带宽的,同时也能减低服务器的压力。

相关推荐