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,肯定是不能夠獲取到指定網站的數據的。