1
如何发起一个HTTP请求?这个问题似乎既简单又复杂,简单是指当你在浏览器里输入一个URL时,按回车键后这个HTTP请求就发起了,很快你就会看到这个请求的返回结果。复杂是指能否不借助浏览器也能发起请求,这里的“不借助”有两层含义,一是指能不能自己组装一个符合HTTP协议的数据包,二是处理浏览器还有哪些方式也能简单地发起一个HTTP请求。下面就按照这两层含义来解释如何发起一个HTTP请求。
如何发起一个HTTP请求和如何建立一个Socket连接区别不大,只不过outputStream. write写的二进制字节数据格式要符合HTTP协议。浏览器在建立Socket连接之前,必须根据地址栏里输入的URL的域名DNS解析出IP地址,再根据这个IP地址和默认80端口与远程服务器建立Socket连接,然后浏览器根据这个URL组装成一个get类型的HTTP请求头,通过outputStream.write发送到目标服务器,服务器等待inputStream.read返回数据,最后断开这个连接。
当然,不同浏览器在如何使用这个已经建立好的连接,以及根据什么规则来管理连接,有各种不同的实现方法。一句话,发起一个HTTP请求的过程就是建立一个Socket通信的过程。
既然发起一个HTTP连接本质上就是建立一个Socket连接,那么我们完全可以模拟浏览器来发起HTTP请求,这很好实现,也有很多方法实现,如HttpClient就是一个开源的通过程序实现的处理HTTP请求的工具包。 当然如果你对HTTP协议的数据结构非常熟悉,你完全可以自己再实现另外一个HttpClient,甚至可以自己写个简单的浏览器。
下面是一个基本的HttpClient的调用示例:
1 HttpClient httpClient = createHttpClient(); 2 PostMethod postMethod; 3 String domainName = Switcher.domain; 4 postMethod = new PostMethod(domainName); 5 postMethod.addRequestHeader("Content-Type", "application/x-www-form- urlencoded; charset=GBK"); 6 for (FilterData filterData : filterDatas) { 7 postMethod.addParameter("ip", filterData.ip); 8 postMethod.addParameter("count", String.valueOf(filterData.count)); 9 } 10 try { 11 httpClient.executeMethod(postMethod); 12 postMethod.getResponseBodyAsString(); 13 } catch (Exception e) { 14 logger.error(e); 15 }
处理Java中使用非常普遍的HttpClient还有很多类似的工具,如Linux中的curl命令,通过curl + URL就可以简单地发起一个HTTP请求,非常方便。
例如,curl "http://item.taobao.com/item.htm?id=1264" 可以返回这个页面的HTML数据,如图1-2所示。

也可以查看这次访问的HTTP协议头的信息,加上-I选项,如图1-3所示。

还可以在访问这个URL时增加HTTP头,通过-HI 选项实现,如图1-4所示。

因为缺少Cookie信息,所以上面的访问返回302状态码,必须增加Cookie才能正确访问该链接,如下所示:
[junshan@v101055.sqa.cm4 admin]$ curl -I
"http://switch.taobao.com:9999/ repository.htm" -H
"Cookie:cna=sd0/BjeZulwCAfIdAHkzZZqC; _t_track=121.0.29.
242.1320938379988839;"
HTTP/1.1 200 OK
Date: Sat, 25 Feb 2012 08:41:20 GMT
Server: Apache
Last-Modified: Thu, 01 Jan 1970 00:00:00 GMT
Vary: Accept-Encoding
Content-Type: text/html;charset=GBK
浙公网安备 33010602011771号