最近搞一个扣网页内容的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);
}
}