官术网_书友最值得收藏!

1.2 如何發起一個請求

如何發起一個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的調用示例:

    HttpClient httpClient = createHttpClient();
          PostMethod postMethod;
          String domainName = Switcher.domain;
          postMethod = new PostMethod(domainName);
          postMethod.addRequestHeader("Content-Type", "application/x-www-form-
urlencoded; charset=GBK");
          for (FilterData filterData : filterDatas) {
              postMethod.addParameter("ip", filterData.ip);
              postMethod.addParameter("count", String.valueOf(filterData.count));
          }
          try {
              httpClient.executeMethod(postMethod);
              postMethod.getResponseBodyAsString();
          } catch (Exception e) {
              logger.error(e);
          }

處理Java中使用非常普遍的HttpClient還有很多類似的工具,如Linux中的curl命令,通過curl + URL就可以簡單地發起一個HTTP請求,非常方便。

例如,curl "http://item.taobao.com/item.htm?id=1264" 可以返回這個頁面的HTML數據,如圖1-2所示。

圖1-2 HTTP請求返回的HTML數據

也可以查看這次訪問的HTTP協議頭的信息,加上-I選項,如圖1-3所示。

圖1-3 HTTP協議頭的信息

還可以在訪問這個URL時增加HTTP頭,通過-HI選項實現,如圖1-4所示。

圖1-4 訪問URL時增加HTTP頭

因為缺少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.1200 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
主站蜘蛛池模板: 施秉县| 乌拉特中旗| 辽阳县| 临西县| 都兰县| 扎兰屯市| 南川市| 麻江县| 雅江县| 长寿区| 兴宁市| 奉节县| 兴义市| 民勤县| 临潭县| 来宾市| 江北区| 道孚县| 揭阳市| 华蓥市| 错那县| 新安县| 微博| 南澳县| 扬中市| 汾西县| 镇原县| 崇明县| 酉阳| 南部县| 霍城县| 武平县| 马关县| 界首市| 昌宁县| 咸宁市| 旺苍县| 昆山市| 织金县| 大城县| 崇阳县|