最近搞一個扣網頁內容的SessionBean,需要模擬客戶端post提交,然后得到servlet返回的結果。
采用Jakarta的HttpClient API解決之.
HttpClient擴展和增強了標準java.net包,是一個內容廣泛的代碼庫,功能極其豐富,能夠構造出各
種使用HTTP協議的分布式應用,或者也可以嵌入到現有應用,為應用增加訪問HTTP協議的能力
要求:
1:CLASSPATH中有commons-httpclient.jar,common-logging.jar
2:確保%JAVA_HOME% /jre/lib/security/java.security文件包含這行代碼:
?security.provider.2= com.sun.net.ssl.internal.ssl.Provider。
一:GET方法測試代碼:
/**/
/*
?*?Created?on?Sep?25,?2006
?*
?*?To?change?the?template?for?this?generated?file?go?to
?*?Window>Preferences>Java>Code?Generation>Code?and?Comments
?
*/
package
?co.iproxy.http;

import
?java.io.IOException;

import
?org.apache.commons.httpclient.HttpClient;
import
?org.apache.commons.httpclient.HttpException;
import
?org.apache.commons.httpclient.HttpStatus;
import
?org.apache.commons.httpclient.methods.GetMethod;


/**?*/
/**
?*?
@author
?lichunlei
?*
?*?To?change?the?template?for?this?generated?type?comment?go?to
?*?Window>Preferences>Java>Code?Generation>Code?and?Comments
?
*/
public
?
class
?HttpClientGetMethodTest

...
{

?
public
?
static
?
void
?main(String[]?args)

?
...
{
??HttpClient?client?
=
?
new
?HttpClient();
??String?url?
=
?
"
http://192.168.0.79:9080/Icare/IcareTest/index.jsp
"
;
??GetMethod?method?
=
?
new
?GetMethod(url);

??
try
??
...
{
???client.executeMethod(method);
???
if
?(method.getStatusCode()?
==
?HttpStatus.SC_OK)

???
...
{
????String?response?
=
?method.getResponseBodyAsString();
????System.out.println(response);
???}
??}
??
catch
?(HttpException?e)

??
...
{
???e.printStackTrace();

??}
??
catch
?(IOException?e)

??
...
{
???e.printStackTrace();
??}
??
finally
??
...
{

???method.releaseConnection();
???method.recycle();
??}
?}
}
二:POST方法測試代碼:
?
/**/
/*
?*?Created?on?Sep?25,?2006
?*
?*?To?change?the?template?for?this?generated?file?go?to
?*?Window>Preferences>Java>Code?Generation>Code?and?Comments
?
*/
package
?co.iproxy.http;

import
?java.io.BufferedReader;
import
?java.io.ByteArrayInputStream;
import
?java.io.File;
import
?java.io.FileNotFoundException;
import
?java.io.FileReader;
import
?java.io.IOException;
import
?java.io.InputStream;

import
?org.apache.commons.httpclient.DefaultMethodRetryHandler;
import
?org.apache.commons.httpclient.HostConfiguration;
import
?org.apache.commons.httpclient.HttpClient;
import
?org.apache.commons.httpclient.HttpStatus;
import
?org.apache.commons.httpclient.methods.PostMethod;


/**?*/
/**
?*?
@author
?lichunlei
?*
?*?To?change?the?template?for?this?generated?type?comment?go?to
?*?Window>Preferences>Java>Code?Generation>Code?and?Comments
?
*/
public
?
class
?HttpClientPostMethodTest

...
{

?
static
?
int
?BASE_BODY_SIZE?
=
?
10240
;
?
static
?
int
?INC_BODY_SIZE?
=
?
51200
;

?
public
?
static
?
void
?main(String[]?args)

?
...
{

??String?request?
=
?
null
;
??String?url?
=
?
"
http://132.201.69.80:5080/BISWeb/Servicelet
"
;
??String?result?
=
?
null
;

??String?filePath?
=
?
"
D:/OPS_piese_idl36(from?cvs)/Ntelagent/co/iproxy/http/request.txt
"
;
??File?f?
=
?
new
?File(filePath);
??FileReader?fileReader?
=
?
null
;
??
try
??
...
{
???fileReader?
=
?
new
?FileReader(f);
???BufferedReader?bufferedReader?
=
?
new
?BufferedReader(fileReader);
???String?currentLine;
???StringBuffer?content?
=
?
new
?StringBuffer();
???
while
?((currentLine?
=
?bufferedReader.readLine())?
!=
?
null
)

???
...
{
????content.append(currentLine);
???}
???request?
=
?content.toString();
??}
??
catch
?(Exception?e1)

??
...
{
???
//
?TODO?Auto-generated?catch?block
???e1.printStackTrace();
??}
??System.out.println(
"
the?request?is:?
"
?
+
?request);

??DefaultMethodRetryHandler?retryhandler?
=
?
new
?DefaultMethodRetryHandler();
??retryhandler.setRequestSentRetryEnabled(
true
);
??retryhandler.setRetryCount(
2
);?
//
?retry?2?times
??HttpClient?httpClient?
=
?
new
?HttpClient();
??PostMethod?method?
=
?
new
?PostMethod(url);

??InputStream?data?
=
?
new
?ByteArrayInputStream(request.getBytes());
??method.setRequestBody(data);

??method.setFollowRedirects(
true
);
??method.setMethodRetryHandler(retryhandler);

??
try
??
...
{

???
//
?execute?the?method
???HostConfiguration?cf?
=
?
new
?HostConfiguration();
???System.out.println(
"
use?proxy
"
);
???cf.setProxy(
"
192.168.254.212
"
,?
4480
);
???httpClient.setHostConfiguration(cf);
???
//
httpClient.setTimeout(10000000);
???
int
?retcode?
=
?httpClient.executeMethod(method);

???
if
?(retcode?
==
?HttpStatus.SC_OK)

???
...
{
????
byte
[]?responseBody?
=
?
new
?
byte
[BASE_BODY_SIZE];
????java.io.InputStream?istream?
=
?method.getResponseBodyAsStream();
????
int
?npos?
=
?
0
;
????
int
?nread?
=
?
0
;
????
while
?((nread?
=
?istream.read(responseBody,?npos,?responseBody.length?
-
?npos))?
>=
?
0
)

????
...
{
?????npos?
+=
?nread;
?????
if
?(npos?
>=
?responseBody.length)

?????
...
{
??????
byte
[]?tmpBuf?
=
?
new
?
byte
[npos?
+
?INC_BODY_SIZE];
??????System.arraycopy(responseBody,?
0
,?tmpBuf,?
0
,?npos);
??????responseBody?
=
?tmpBuf;
?????}
????}
????result?
=
?
new
?String(responseBody,?
0
,?npos);
???}
???
else
???
...
{
????
throw
?
new
?IOException(
"
failed?to?send?request:?retcode:?
"
?
+
?retcode);
???}
??}
??
catch
?(Exception?e)

??
...
{
??}
??
finally
??
...
{
???System.out.println(
"
lcl?test?in?httpClient:
"
?
+
?result);

??}
?}
}
以上兩個class已經包含了大部分常用的模擬http客戶端的技術了,包括設置代理服務器,提交表單,得到返回結果等.
通過上面的測試代碼,已經可以初步解決扣網頁的問題了.現在備份一下我的實現方法(不是很通用,需要進一步完善), 同時也供大家參考.
/**/
/*
?*?Created?on?Sep?25,?2006
?*
?*?To?change?the?template?for?this?generated?file?go?to
?*?Window>Preferences>Java>Code?Generation>Code?and?Comments
?
*/
package
?co.iproxy.http;

import
?java.io.ByteArrayInputStream;
import
?java.io.IOException;
import
?java.io.InputStream;

import
?java.net.MalformedURLException;

import
?org.apache.commons.httpclient.DefaultMethodRetryHandler;
import
?org.apache.commons.httpclient.HostConfiguration;
import
?org.apache.commons.httpclient.HttpClient;
import
?org.apache.commons.httpclient.HttpStatus;
import
?org.apache.commons.httpclient.methods.PostMethod;


/**?*/
/**
?*?
@author
?lichunlei
?*
?*?To?change?the?template?for?this?generated?type?comment?go?to
?*?Window>Preferences>Java>Code?Generation>Code?and?Comments
?
*/
public
?
class
?HttpService?
implements
?ServiceInterface?
...
{

?
private
?HttpClient?httpClient?
=
?
new
?HttpClient();

?
private
?DefaultMethodRetryHandler?retryhandler?
=
?
null
;

?
private
?String?url?
=
?
null
;

?
static
?
int
?BASE_BODY_SIZE?
=
?
10240
;
?
static
?
int
?INC_BODY_SIZE?
=
?
51200
;


?
public
?HttpService()?
throws
?MalformedURLException?
...
{
??
this
.createMethodRetryHandler();
??
this
.setHostConfiguration();
?}
?
private
?
void
?createMethodRetryHandler()?
...
{
??retryhandler?
=
?
new
?DefaultMethodRetryHandler();
??retryhandler.setRequestSentRetryEnabled(
true
);
??retryhandler.setRetryCount(
2
);?
//
?retry?2?times
?}
?
private
?
void
?setHostConfiguration()?
throws
?MalformedURLException?
...
{
??
this
.url?
=
?
"
http://132.201.69.80:5080/BISWeb/Servicelet
"
;
??String?host?
=
?
"
132.201.69.80
"
;
??
int
?port?
=
?
5080
;

??String?protocol?
=
?
"
http
"
;


??
if
?(url?
!=
?
null
?
&&
?
!
url.trim().equals(
""
))?
...
{
???java.net.URL?nurl?
=
?
new
?java.net.URL(url);
???host?
=
?nurl.getHost();
???port?
=
?nurl.getPort();
???protocol?
=
?nurl.getProtocol();
??}
??setHostConfiguration(host,?port,?protocol);
?}
?
/**?*/
/**
??*?Set?host?configuration
??*
??*?
@param
?host?host?name/ip
??*?
@param
?port?port?number
??*?
@param
?protocol?protocol?name?(e.g.?"jakarta.apache.org"?)
??
*/
?
private
?
void
?setHostConfiguration(String?host,?
int
?port,?String?protocol)?
...
{
??
//
?Set?the?default?host/protocol?for?the?methods?to?connect?to.
??
//
?This?value?will?only?be?used?if?the?methods?are?not?given?an?absolute?URI
??httpClient.getHostConfiguration().setHost(
???((host?
==
?
null
?
||
?host.trim().equals(
""
))?
?
?
"
localhost
"
?:?host),
???(port?
<=
?
0
?
?
?
80
?:?port),
???((protocol?
==
?
null
?
||
?protocol.trim().equals(
""
))
????
?
?
"
http
"
????:?protocol));
?}
?
public
?String?process(String?request)?
throws
?IOException?
...
{
??String?result?
=
?
null
;
??PostMethod?method?
=
?
new
?PostMethod(url);

??InputStream?data?
=
?
new
?ByteArrayInputStream(request.getBytes());
??method.setRequestBody(data);
??method.setFollowRedirects(
true
);
??method.setMethodRetryHandler(retryhandler);


??
try
?
...
{
???
//
?execute?the?method
???HostConfiguration?cf?
=
?
new
?HostConfiguration();
???System.out.println(
"
use?proxy
"
);
???cf.setProxy(
"
192.168.254.212
"
,?
4480
);
???httpClient.setHostConfiguration(cf);
???
//
httpClient.setTimeout(10000000);
???
int
?retcode?
=
?httpClient.executeMethod(method);

???
if
?(retcode?
==
?HttpStatus.SC_OK)?
...
{
????
byte
[]?responseBody?
=
?
new
?
byte
[BASE_BODY_SIZE];
????
//
?byte[]?responseBody?=?body;
????java.io.InputStream?istream?
=
?method.getResponseBodyAsStream();
????
int
?npos?
=
?
0
;
????
int
?nread?
=
?
0
;
????
while
?((nread?
=
?????istream.read(
??????responseBody,
??????npos,
??????responseBody.length?
-
?npos))

?????
>=
?
0
)?
...
{
?????npos?
+=
?nread;

?????
if
?(npos?
>=
?responseBody.length)?
...
{
??????
byte
[]?tmpBuf?
=
?
new
?
byte
[npos?
+
?INC_BODY_SIZE];
??????System.arraycopy(responseBody,?
0
,?tmpBuf,?
0
,?npos);
??????responseBody?
=
?tmpBuf;
?????}
????}
????
//
?byte[]?responseBody?=?method.getResponseBody();
????result?
=
?
new
?String(responseBody,?
0
,?npos);

???}
?
else
?
...
{
????
throw
?
new
?IOException(
?????
"
failed?to?send?request:?retcode:?
"
?
+
?retcode);
???}
??}
?
catch
?(java.io.IOException?iex)?
...
{
???
throw
?iex;

??}
?
finally
?
...
{
???
//
?always?release?the?connection?after?the?request?is?done
???method.releaseConnection();

???
if
?(data?
!=
?
null
)?
...
{

????
try
?
...
{
?????data.close();

????}
?
catch
?(Exception?ex)?
...
{

????}
???}
??}
??
return
?result;
?}
?
/**/
/*
?(non-Javadoc)
??*?@see?co.iproxy.http.ServiceInterface#syncRequest(java.lang.String)
??
*/
?
public
?String?syncRequest(String?request)?
throws
?IOException?
...
{
??
return
?
this
.process(request);
?}
?
/**/
/*
?(non-Javadoc)
??*?@see?co.iproxy.http.ServiceInterface#asyncRequest(java.lang.String)
??
*/
?
public
?String?request(String?request)?
throws
?IOException?
...
{
??
return
?
this
.process(request);
?}
}