Posted on 2009-12-14 22:38
Gavin.lee 閱讀(5774)
評論(0) 編輯 收藏 所屬分類:
java SE & EE
HttpClient 是 Apache Jakarta Common 下的子項目,可以用來提供高效的、最新的、功能豐富的支持 HTTP 協議的客戶端編程工具包,并且它支持 HTTP 協議最新的版本和建議。
HTTP 協議可能是現在 Internet 上使用得最多、最重要的協議了,越來越多的 Java 應用程序需要直接通過 HTTP 協議來訪問網絡資源。雖然在 JDK 的 java.net 包中已經提供了訪問 HTTP 協議的基本功能,但是對于大部分應用程序來說,JDK 庫本身提供的功能還不夠豐富和靈活。HttpClient 是 Apache Jakarta Common 下的子項目,用來提供高效的、最新的、功能豐富的支持 HTTP 協議的客戶端編程工具包,并且它支持 HTTP 協議最新的版本和建議。HttpClient 已經應用在很多的項目中,比如 Apache Jakarta 上很著名的另外兩個開源項目 Cactus 和 HTMLUnit 都使用了 HttpClient,更多使用 HttpClient 的應用可以參見http://wiki.apache.org/jakarta-httpclient/HttpClientPowered。HttpClient 項目非?;钴S,使用的人還是非常多的。
使用HttpClient用到的jar包:commons-codec.jar,commons-httpclient-3.0.jar
package com.yixun.wap;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.httpclient.Cookie;
import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HostConfiguration;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpState;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.URI;
import org.apache.commons.httpclient.cookie.CookiePolicy;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.commons.httpclient.params.HttpConnectionManagerParams;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.commons.httpclient.protocol.Protocol;
import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;
import org.apache.commons.httpclient.protocol.SSLProtocolSocketFactory;


/** *//**
* HttpClient 使用
* 1.GET/POST(HEAD,PUT)
* 2.Proxy
* 3.Https
* 4.Cookie
* 5.字符編碼
* 6.支持自動轉向
* @author Administrator
*
*/

public class HttpClientCenter
{

static HttpClient httpClient = null;
//構造HttpClient的實例
private static HttpClientCenter instance;

private HttpClientCenter()
{
httpClient = new HttpClient();

public static HttpClientCenter getInstance()
{

if(instance == null)
{
return new HttpClientCenter();
}
return instance;
}
//Https

/** *//**
* 設置代理
* 代理服務器是位于客戶端和Web服務器之間一個中間服務器。我們通過使用瀏覽器中配置的相應代理,
* 將請求發送到代理服務器,代理服務器代理我們客戶端去請求Web服務器,將請求到的響應資源再次
* 響應我們客戶端,同時緩存到代理服務器上,以備下次客戶端請求代理服務器的時候,直接從代理服
* 務器上取得要請求的資源,而無需再次請求網站的Web服務器,提高了響應速度。
*/

/** *//**
* GET請求
* 使用 HttpClient 需要以下 6 個步驟:
* 1. 創建 HttpClient 的實例
* 2. 創建某種連接方法的實例,在這里是 GetMethod。在 GetMethod 的構造函數中傳入待連接的地址
* 3. 調用第一步中創建好的實例的 execute 方法來執行第二步中創建好的 method 實例
* 4. 讀 response
* 5. 釋放連接。無論執行方法是否成功,都必須釋放連接
* 6. 對得到后的內容進行處理
* @param url
*/

public void getMethod(String url)
{
GetMethod getMethod = null;

try
{
URI uri = new URI(url, true);
getMethod = new GetMethod(url);// 創建GET方法的實例,可同時對請求的頭,等等,做相應的設置

/** *//** 設置代理*/
HostConfiguration hostConfiguration = new HostConfiguration();
hostConfiguration.setHost(uri);
hostConfiguration.setProxy("127.0.0.1", 8080);// 配置代理IP和端口
httpClient.setHostConfiguration(hostConfiguration);
// 使用系統提供的默認的恢復策略
getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler());
HttpConnectionManagerParams managerParams = httpClient.getHttpConnectionManager().getParams();
managerParams.setConnectionTimeout(30000); // 設置連接超時時間(單位毫秒)
managerParams.setSoTimeout(120000); //設置讀數據超時時間(單位毫秒)
int statusCode = httpClient.executeMethod(getMethod);// 執行getMethod,返回響應碼

if (statusCode != HttpStatus.SC_OK)
{
System.err.println("Method failed: " + getMethod.getStatusLine()); //Method failed: HTTP/1.1 200 OK
}
String charSet = getMethod.getResponseCharSet(); //響應的字符編碼
byte[] responseBody = getMethod.getResponseBody(); // 讀取內容
System.out.println("responseCode:\r\n" + statusCode);
System.out.println("charSet:\r\n" + charSet);
System.out.println("response:\r\n" + new String(responseBody, charSet));
Header headers[] = getMethod.getResponseHeaders();

for(int i = 0; i < headers.length; i ++)
{
System.out.println(headers[i]);
}

/**//*Date: Mon, 21 Dec 2009 16:34:06 GMT
Content-Type: text/vnd.wap.wml; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Server: Resin/3.1.0
Cache-Control: no-cache
Expires: Thu, 01 Dec 1994 16:00:00 GMT
Set-Cookie: JSESSIONID=abc8cwOo6fWhcf2uQfYws; path=/
P3P: policyref="http://www.500wan.com/w3c/P3P.xml" CP="NOI ADM DEV PSAi COM NAV OUR OTR STP IND DEM"
*/

} catch (HttpException e)
{
e.printStackTrace();// 發生致命的異常,可能是協議不對或者返回的內容有問題

} catch (IOException e)
{
e.printStackTrace();// 發生網絡異常

} finally
{
getMethod.releaseConnection();// 釋放連接
}
}


public void postMethod(String url, Map<Object, Object> datas)
{
PostMethod postMethod = new PostMethod(url);

/** *//** 設置代理---同上GET方法*/
int params = datas.size();
NameValuePair[] data = new NameValuePair[params];
int i = 0;

for (Object obj : datas.keySet())
{
data[i++] = new NameValuePair((String)obj, (String)datas.get(obj));
}
// NameValuePair[] data = {new NameValuePair("id", "youUserName"), new NameValuePair("passwd", "yourPwd") };//填入各個表單域的值
// postMethod.setRequestEntity(new StringRequestEntity("createRequestXML()", "text/xml", "GBK")); 可使用XML格式傳輸post參數
postMethod.setRequestBody(data);//將表單的值放入postMethod中

try
{
HttpConnectionManagerParams managerParams = httpClient.getHttpConnectionManager().getParams();
managerParams.setConnectionTimeout(30000); // 設置連接超時時間(單位毫秒)
managerParams.setSoTimeout(120000); // 設置讀數據超時時間(單位毫秒)
int statusCode = httpClient.executeMethod(postMethod);// 執行postMethod
//HttpClient對于要求接受后繼服務的請求,象POST和PUT等不能自動處理轉發

if (statusCode == HttpStatus.SC_MOVED_PERMANENTLY || statusCode == HttpStatus.SC_MOVED_TEMPORARILY)
{//301或者302
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;
}

} catch (IOException e)
{
e.printStackTrace();
}
}

public void cookieSet()
{
httpClient.getParams().setCookiePolicy(CookiePolicy.RFC_2109);// RFC_2109是支持較普遍的一個,還有其他cookie協議
HttpState initialState = new HttpState();
Cookie cookie = new Cookie();
cookie.setDomain("www.balblabla.com");
cookie.setPath("/");
cookie.setName("多情環");
cookie.setValue("多情即無情");
initialState.addCookie(cookie);
httpClient.setState(initialState);
}

public void cookieGet()
{
Cookie[] cookies = httpClient.getState().getCookies();
System.out.println("Present cookies: ");

for (int i = 0; i < cookies.length; i++)
{
System.out.println(" - " + cookies[i].toExternalForm());
System.out.println(" - domain=" + cookies[i].getDomain());
System.out.println(" - path=" + cookies[i].getPath());
}
}

public static void main(String args[])
{
HttpClientCenter hcc = HttpClientCenter.getInstance();
String url = "http://www.500wan.com/";
url = "http://wap.500wan.com";
// hcc.getMethod(url);
Map<Object, Object> datas = new HashMap<Object, Object>();
datas.put("id", "1001");
datas.put("pass", "123456");
hcc.postMethod(url, datas);
}
}
