HttpClient中配置HTTP參數

關於HttpClient不多說,可以到apache網站下載,網上文檔的也多如牛毛。針對HttpClient-3.1,我認爲比較重要的一部分就是配置HTTP的參數。實際上,按HttpClient默認的參數配置也可以做簡單的應用,其中對於參數配置問題,我覺得雖然比較亂,但是掌握了HttpClient應用參數繼承的繼承機制,就非常明白了。

HttpClient-3.1中,參數繼承結構如圖所示:

global--+                            | DefaultHttpParams
        |                            |
      client                         | HttpClient
        |                            |
        +-- connection manager       | HttpConnectionManager
        |     |                      |
        |     +-- connection         | HttpConnection
        |                            |
        +-- host                     | HostConfiguration
              |                      |
              +-- method             | HttpMethod
HttpClient中配置HTTP參數通過上面的繼承結構可以看到,HttpClient在參數配置上分爲6個級別,分別爲:global、client、connection manager、connection、host、method。下面結合HttpClient-3.1的文檔和源代碼,說說這6個級別的含義。

HttpClient參數配置因爲分爲6個級別,可能導致在HttpClient參數的重複配置。但是,文檔上也說明了,HttpClient在工作的過程中,是按照繼承層次查找參數配置,如果在某個最低級別上沒有配置某個參數,程序會自動向上一級別查找,直到查找到該參數在某個級別中被配置過,然後運行時按照,距離參數配置級別最低層最近的原則,進行配置。如果都沒有配置,自然就按global級別執行。

當你創建HttpClient和HttpMethod實例的時候,可以不用配置就執行HttpMethod,它會按照global級別配置,如果你對它們進行了配置,而且參數配置級別低於global級別,global級別參數配置就被覆蓋。通過上面的繼承層次可以看到,每個不同的級別都對應着一個實體,從高到低依次爲DefaultHttpParams、HttpClient、HttpConnectionManager、HttpConnection、HostConfiguration、HttpMethod。

關於各個級別是如何規定的,並在都可以配置哪些參數,可以參考Apache官方網站幫助文檔http://hc.apache.org/httpclient-3.x/preference-api.html,下面舉個例子說明一下:

主要通過使用http.socket.timeout參數,其中,HttpClient、HttpConnectionManager、HttpMethod都可以對幹參數進行配置,代碼如下所示:

package org.shirdrn.test;

import java.io.IOException;

import org.apache.commons.httpclient.HostConfiguration;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpMethodBase;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.URI;
import org.apache.commons.httpclient.URIException;
import org.apache.commons.httpclient.methods.GetMethod;

public class MyHttpClient {

private HttpClient client;
private HttpMethodBase method;
private String stringData;

public MyHttpClient() {
   this.client = new HttpClient();
   this.method = new GetMethod();
}

public void setParams(String url) throws URIException, NullPointerException {
   this.client.getParams().setParameter("http.socket.timeout", 1); //   爲HttpClient設置參數
   this.client.getHttpConnectionManager().getParams().setParameter("http.socket.timeout", 1); //   爲HttpConnetionManager設置參數

   this.method.getParams().setParameter("http.socket.timeout", 10000); //   爲HttpMethod設置參數

   HostConfiguration hostConf = new HostConfiguration();
   hostConf.setHost(new URI(url, true));
   this.client.setHostConfiguration(hostConf);
}

public void execute() throws HttpException, IOException {
   int status = this.client.executeMethod(this.method);
   if(status == HttpStatus.SC_OK) {
    this.stringData = new String(this.method.getResponseBody(), "gb2312");
   }
}

public void print() {
   System.out.println(this.stringData);
}

public static void main(String[] args) {
   MyHttpClient client = new MyHttpClient();
   try {
    client.setParams("http://www.csdn.net");
    client.execute();
    client.print();
   } catch (Exception e) {
    e.printStackTrace();
   }
}
}

上面程序中,分別對HttpClient、HttpConnectionManager、HttpMethod三個級別配置了http.socket.timeout參數,直接運行可以看到指定網站的頁面數據被下載下來,可見,是HttpMethod設置的超時參數起作用了。所以它的級別在上述三個級別中是最低的。

可以測試一下,將HttpConnectionManager、HttpMethod設置的參數全部註釋掉,再執行上述程序,就會發生Socket超時異常:

java.net.SocketTimeoutException: Read timed out
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:218)
at java.io.BufferedInputStream.read(BufferedInputStream.java:237)
at org.apache.commons.httpclient.HttpParser.readRawLine(HttpParser.java:78)
at org.apache.commons.httpclient.HttpParser.readLine(HttpParser.java:106)
at org.apache.commons.httpclient.HttpConnection.readLine(HttpConnection.java:1116)
at org.apache.commons.httpclient.HttpMethodBase.readStatusLine(HttpMethodBase.java:1973)
at org.apache.commons.httpclient.HttpMethodBase.readResponse(HttpMethodBase.java:1735)
at org.apache.commons.httpclient.HttpMethodBase.execute(HttpMethodBase.java:1098)
at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:398)
at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:171)
at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:397)
at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:323)
at org.shirdrn.test.MyHttpClient.execute(MyHttpClient.java:35)
at org.shirdrn.test.MyHttpClient.main(MyHttpClient.java:49)

因爲HttpClient設置了Socket超時時間爲1ms,肯定是不能夠獲取到指定網站的數據的。
發佈了46 篇原創文章 · 獲贊 33 · 訪問量 33萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章