一般的情況下我們都是使用IE或者Navigator瀏覽器來訪問一個WEB服務器,用來瀏覽頁面查看信息或者提交一些數據等等。所訪問的這些頁面 有的僅僅是一些普通的頁面,有的需要用戶登錄后方可使用,或者需要認證以及是一些通過加密方式傳輸,例如HTTPS。目前我們使用的瀏覽器處理這些情況都 不會構成問題。不過你可能在某些時候需要通過程序來訪問這樣的一些頁面,比如從別人的網頁中“偷”一些數據;利用某些站點提供的頁面來完成某種功能,例如 說我們想知道某個手機號碼的歸屬地而我們自己又沒有這樣的數據,因此只好借助其他公司已有的網站來完成這個功能,這個時候我們需要向網頁提交手機號碼並從 返回的頁面中解析出我們想要的數據來。如果對方僅僅是一個很簡單的頁面,那我們的程序會很簡單,本文也就沒有必要大張旗鼓的在這里浪費口舌。但是考慮到一 些服務授權的問題,很多公司提供的頁面往往並不是可以通過一個簡單的URL就可以訪問的,而必須經過注冊然后登錄后方可使用提供服務的頁面,這個時候就涉 及到COOKIE問題的處理。我們知道目前流行的動態網頁技術例如ASP、JSP無不是通過COOKIE來處理會話信息的。為了使我們的程序能使用別人所 提供的服務頁面,就要求程序首先登錄后再訪問服務頁面,這過程就需要自行處理cookie,想想當你用 java.net.HttpURLConnection來完成這些功能時是多么恐怖的事情啊!況且這僅僅是我們所說的頑固的WEB服務器中的一個很常見的 “頑固”!再有如通過HTTP來上傳文件呢?不需要頭疼,這些問題有了“它”就很容易解決了!
我們不可能列舉所有可能的頑固,我們會 針對幾種最常見的問題進行處理。當然了,正如前面說到的,如果我們自己使用java.net.HttpURLConnection來搞定這些問題是很恐怖 的事情,因此在開始之前我們先要介紹一下一個開放源碼的項目,這個項目就是Apache開源組織中的httpclient,它隸屬於Jakarta的 commons項目,目前的版本是2.0RC2。commons下本來已經有一個net的子項目,但是又把httpclient單獨提出來,可見http 服務器的訪問絕非易事。
Commons-httpclient項目就是專門設計來簡化HTTP客戶端與服務器進行各種通訊編程。通過它可 以讓原來很頭疼的事情現在輕松的解決,例如你不再管是HTTP或者HTTPS的通訊方式,告訴它你想使用HTTPS方式,剩下的事情交給 httpclient替你完成。本文會針對我們在編寫HTTP客戶端程序時經常碰到的幾個問題進行分別介紹如何使用httpclient來解決它們,為了 讓讀者更快的熟悉這個項目我們最開始先給出一個簡單的例子來讀取一個網頁的內容,然后循序漸進解決掉前進中的所有問題。
1. 讀取網頁(HTTP/HTTPS)內容
下面是我們給出的一個簡單的例子用來訪問某個頁面
/**//*
* Created on 2003-12-14 by Liudong
*/
package http.demo;
import java.io.IOException;
import org.apache.commons.httpclient.*;
import org.apache.commons.httpclient.methods.*;
/** *//**
* 最簡單的HTTP客戶端,用來演示通過GET或者POST方式訪問某個頁面
* @author Liudong
*/
public class SimpleClient ...{
public static void main(String[] args) throws IOException
...{
HttpClient client = new HttpClient();
//設置代理服務器地址和端口
//client.getHostConfiguration().setProxy("proxy_host_addr",proxy_port);
//使用GET方法,如果服務器需要通過HTTPS連接,那只需要將下面URL中的http換成https
HttpMethod method = new GetMethod("http://java.sun.com";);
//使用POST方法
//HttpMethod method = new PostMethod("http://java.sun.com";);
client.executeMethod(method);
//打印服務器返回的狀態
System.out.println(method.getStatusLine());
//打印返回的信息
System.out.println(method.getResponseBodyAsString());
//釋放連接
method.releaseConnection();
}
}
在這個例子中首先創建一個HTTP客戶端(HttpClient)的實例,然后選擇提交的方法是GET或者POST,最后在HttpClient實 例上執行提交的方法,最后從所選擇的提交方法中讀取服務器反饋回來的結果。這就是使用HttpClient的基本流程。其實用一行代碼也就可以搞定整個請 求的過程,非常的簡單!
2. 以GET或者POST方式向網頁提交參數
其實前面一個最簡單的示例中我們已經介紹了如何使用 GET或者POST方式來請求一個頁面,本小節與之不同的是多了提交時設定頁面所需的參數,我們知道如果是GET的請求方式,那么所有參數都直接放到頁面 的URL后面用問號與頁面地址隔開,每個參數用&隔開,例如:http://java.sun.com/?name=liudong&mobile=123456,但是當使用POST方法時就會稍微有一點點麻煩。本小節的例子演示向如何查詢手機號碼所在的城市,代碼如下:
/**//*
* Created on 2003-12-7 by Liudong
*/
package http.demo;
import java.io.IOException;
import org.apache.commons.httpclient.*;
import org.apache.commons.httpclient.methods.*;
/** *//**
* 提交參數演示
* 該程序連接到一個用於查詢手機號碼所屬地的頁面
* 以便查詢號碼段1330227所在的省份以及城市
* @author Liudong
*/
public class SimpleHttpClient ...{
public static void main(String[] args) throws IOException
...{
HttpClient client = new HttpClient();
client.getHostConfiguration().setHost("www.imobile.com.cn", 80, "http");
HttpMethod method = getPostMethod();//使用POST方式提交數據
client.executeMethod(method);
//打印服務器返回的狀態
System.out.println(method.getStatusLine());
//打印結果頁面
String response = new String(method.getResponseBodyAsString().getBytes("8859_1"));
//打印返回的信息
System.out.println(response);
method.releaseConnection();
}
/** *//**
* 使用GET方式提交數據
* @return
*/
private static HttpMethod getGetMethod()...{
return new GetMethod("/simcard.php?simcard=1330227");
}
/** *//**
* 使用POST方式提交數據
* @return
*/
private static HttpMethod getPostMethod()...{
PostMethod post = new PostMethod("/simcard.php");
NameValuePair simcard = new NameValuePair("simcard","1330227");
post.setRequestBody(new NameValuePair[] ...{ simcard});
return post;
}
}
在上面的例子中頁面http://www.imobile.com.cn/simcard.php需要一個參數是simcard,這個參數值為手機號碼段,即手機號碼的前七位,服務器會返回提交的手機號碼對應的省份、城市以及其他詳細信息。GET的提交方法只需要在URL后加入參數信息,而POST則需要通過NameValuePair類來設置參數名稱和它所對應的值.