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