HttpClient 功能介紹
(1)實現了所有 HTTP 的方法(GET,POST,PUT,HEAD 等)
(2)支持自動轉向
(3)支持 HTTPS 協議
(4)支持代理服務器等
HttpClient 基本功能的使用:共要3個Jar包 commons-codec.jar commons-httpclient.jar commons-logging.jar
(1) GET方法
使用 HttpClient 需要以下 6 個步驟:
1. 創建 HttpClient 的實例
HttpClient httpClient = new HttpClient();
GetMethod method =null
2. 創建某種連接方法的實例。在構造函數中傳入待連接的地址
method=new GetMethod(url);
3. 調用HttpClient的 execute 方法來執行GetMethod 實例
int retcode = httpClient.executeMethod(method);
if (retcode != HttpStatus.SC_OK) {// 發送不成功
facesMessages.add("查詢出錯不成功");
} else {
4. 讀 response —— body = method.getResponseBodyAsString();
}
5. 釋放連接。無論執行方法是否成功,都必須釋放連接
if (method != null) {
method.releaseConnection();
}
6. 對得到後的內容進行處理
備註:
httpClient.getParams().setBooleanParameter("http.protocol.expect-continue", false); method.setRequestHeader("Connection", "close"); //解決Httpclient遠程請求所造成Socket沒有釋放
method=new GetMethod(url);
method.addRequestHeader("Accept", "text/plain");
method.addRequestHeader("Content-Type",
"application/x-www-form-urlencoded;charset=UTF-8");
(2)POST方法
POST方法用來向目的服務器發出請求,要求它接受被附在請求後的實體,並把它當作請求隊列(Request-Line)中請求URI所指定資源的附加新子項。POST被設計成用統一的方法實現下列功能:
對現有資源的註釋(Annotation of existing resources)
向電子公告欄、新聞組,郵件列表或類似討論組發送消息
提交數據塊,如將表單的結果提交給數據處理過程
通過附加操作來擴展數據庫
1. 創建 HttpClient 的實例
HttpClient httpClient = new HttpClient();
PostMethod postMethod=null;
2. 創建某種連接方法的實例。在構造函數中傳入待連接的地址
method=new GetMethod(url);
填入各個表單域的值
NameValuePair[] data = { new NameValuePair("id", "youUserName"),
new NameValuePair("passwd", "yourPwd") };
將表單的值放入postMethod中
postMethod.setRequestBody(data);
3. 調用HttpClient的 execute 方法來執行PostMethod實例
int statusCode = httpClient.executeMethod(method);
if (statusCode!= HttpStatus.SC_OK) {// 發送不成功
facesMessages.add("查詢出錯不成功");
} else {
4. 讀 response —— body = method.getResponseBodyAsString();
}
5. 釋放連接。無論執行方法是否成功,都必須釋放連接
if (method != null) {
method.releaseConnection();
}
6. 對得到後的內容進行處理
備註:
HttpClient對於要求接受後繼服務的請求,象POST和PUT等不能自動處理轉發 // 301或者302
if (statusCode == HttpStatus.SC_MOVED_PERMANENTLY || statusCode == HttpStatus.SC_MOVED_TEMPORARILY) {// 從頭中取出轉向的地址
Header locationHeader = postMethod.getResponseHeader("location");
String location = null;
if (locationHeader != null) {
location = locationHeader.getValue();
System.out.println("The page was redirected to:" + location);
} else {
System.err.println("Location field value is null.");
}
return;
}
3使用HttpClient過程中常見的一些問題
字符編碼
通過method對象的getResponseCharSet()方法就可以得到http頭中的編碼信息
自動轉向
根據RFC2616中對自動轉向的定義,主要有兩種:301和302。301表示永久的移走 (Moved Permanently),當返回的是301,則表示請求的資源已經被移到一個固定的新地方,任何向該地址發起請求都會被轉到新的地址上。302表示暫時 的轉向,比如在服務器端的servlet程序調用了sendRedirect方法,則在客戶端就會得到一個302的代碼,這時服務器返回的頭信息中 location的值就是sendRedirect轉向的目標地址。
HttpClient支持自動轉向處理,但是象POST和PUT方式這種要求接受後繼服務的請求方式,暫時不支持自動轉向,因此如果碰到POST方式提交 後返回的是301或者302的話需要自己處理。就像剛纔在POSTMethod中舉的例子:如果想進入登錄BBS後的頁面,必須重新發起登錄的請求,請求的地址可以在頭字段location中得到。不過需要注意的是,有時候location返回的可能是相對路徑,因此需要對location返回的值做一些 處理纔可以發起向新地址的請求。
另外除了在頭中包含的信息可能使頁面發生重定向外,在頁面中也有可能會發生頁面的重定向。引起頁面自動轉發的標籤是:<meta http-equiv="refresh" content="5; url=....">。如果你想在程序中也處理這種情況的話得自己分析頁面來實現轉向。需要注意的是,在上面那個標籤中url的值也可以是一個相對 地址,如果是這樣的話,需要對它做一些處理後纔可以轉發
5 處理代理服務器
HttpClient中使用代理服務器非常簡單,調用HttpClient中setProxy方法就可以,方法的第一個參數是代理服務器地址,第二個參數是端口號。另外HttpClient也支持SOCKS代理。
httpClient.getHostConfiguration().setProxy(hostName,port);
擴展閱讀:
1.http://hc.apache.org/httpclient-3.x/ HttpClient官方網站
2.http://jakarta.apache.org/commons/httpclient/ HttpClient首頁
3.http://hc.apache.org/downloads.cgi HttpClient下載
4.http://www.leadtoit.cn/subject.php?id=6 力度IT網HttpClient專題
5.http://www.blogjava.net/Alpha/archive/2007/01/22/95216.html HttpClient 學習整理
6.http://www.ibm.com/developerworks/cn/opensource/os-httpclient/ HttpClient入門
7.http://blog.csdn.net/ambitiontan/archive/2006/01/06/572171.aspx 應用HttpClient來對付各種頑固的WEB服務器
8.http://www.pmjava.com/Article/ShowInfo.asp?ID=2147 httpclient 4.0的例子
實例 :
private void send(String url,String requestXml){
String body = "";
PostMethod postMethod=null;
try {
HttpClient httpClient = new HttpClient();
httpClient.getParams().setBooleanParameter("http.protocol.expect-continue", false);
postMethod=new PostMethod(url);
NameValuePair[] dataxml = { new NameValuePair("data", requestXml)};
postMethod.setRequestBody(dataxml);
postMethod.addRequestHeader("Accept", "text/plain");
postMethod.addRequestHeader("Content-Type",
"application/x-www-form-urlencoded;charset=UTF-8");
postMethod.setRequestHeader("Connection", "close");
int retcode = httpClient.executeMethod(postMethod);
if (retcode != HttpStatus.SC_OK) {// 發送不成功
facesMessages.add("查詢出錯不成功");
} else {
body = postMethod.getResponseBodyAsString();
if ("201".equals(body) ) {
facesMessages.add("您對編號爲" + complaint.getNumber() + "的投訴做“待改進”操作成功,即發送其到了QSI系統!!");
} else {
facesMessages.add("您對編號爲" + complaint.getNumber() + "的投訴做“待改進”操作失敗!!");
}
}
} catch (Exception e) {
facesMessages.add("對不起,由於發生某種異常而未能正常查詢訂單信息。請重新再試!!!");
log.error("", e, "");
}finally{
if (postMethod != null) {
postMethod.releaseConnection();
}
}
}
博文轉自:http://blog.csdn.net/charlies_fu/article/details/7948977